数学问题

  • 全排列代码
// 输出全排列--伪代码
int permutation(char a[]) {
    int length = sizeof(a);
    if (length == 0) {
        return;
    }
    for (int i = 0; i < length;i++) {
        cout << a[i];
        // a.delete(a[i]); 删除a[i]
        permutation(a);
    }
}
  • 日期转化与加减
  • 数位拆解与进制转化

数位拆解:

https://www.nowcoder.com/practice/a5edebf0622045468436c74c3a34240f?tpId=40&tqId=21349&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking

十进制数 x 转换成 N 进制数 f :

while (x != 0){
    A[i] = x % N ;
    x = x / N;
    i++;
}
f = A[i]A[i - 1]A[i - 2]...A[0]

N 进制数 f 转换成 十进制数 x :

x = 0;
while (i >= 0){
    x += A[i] * N^i;
    i--;
}

https://www.nowcoder.com/practice/8ef02ef8571b417d8c311a87861f7a03?tpId=40&tqId=21387&tPage=3&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking

  • 最小公倍数LCM与最大公约数GCD

a 和 b 的最大公约数也是 b 和 a mod b的最大公约数,所以循环直至其一为 0,则不为0的就是最大公约数。

int gcd(int a, int b) {
    return b!=0? gcd(b, a%b) : a;
}

a 和 b 的最小公倍数和最小公约数的积等于a 和 b的积。

// lcm= a*b / gcd
int lcm(int a, int b) {
    return a*b/gcd(a, b);
}

https://www.nowcoder.com/practice/20216f2c84bc438eb5ef05e382536fd3?tpId=40&tqId=21492&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking

  • 素数筛法与整数分解

分解素因数 ---- 整除问题

求正整数N(1<N<10^9)的质因数的个数。 相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。
输入:120
输出:5

/* 用 2 到 sqrt(N)内的质数逐个去除 N ,直到 N 为 1即被除尽,
    或者质数全部除完,N不为 1, 但剩余的N必是大于 sqrt(N) 的质数。*/
#include<iostream>
#include<math.h>
using namespace std;
bool prime[100001];
void init(){
    for (int i = 0; i < 100001; i++){
        if (prime[i]){
            continue;
        }
        else{
            int num = sqrt(i);
            for (int j = 2; j < num + 1; j++){
                if (i%j == 0){
                    for (int k = i; k < 100001; k += i){
                        prime[k] = true;
                    }
                    break;
                }
            }
        }
    }
}
int main() {
    int a;
    int num = 0; 
    init();
    cin >> a;
    int i = 2;
    do{
        while (prime[i]){
            i++;
        }
        while (a%i == 0){
            num++;
            a = a / i;
        }
        i++;
    } while (a != 1&&i<100001);
    if (a != 1){
        num++;
    }
    cout << num << endl;
    return 0;
}

https://www.nowcoder.com/practice/20426b85f7fc4ba8b0844cc04807fbd9?tpId=40&tqId=21338&tPage=1&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking

整数拆解

所谓整数划分,是指把一个正整数n写成如下形式:

n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分。

如果{m1,m2,m3,....,mi}中的最大值不超过m,即max{m1,m2,m3,....,mi} <= m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m);

例如当n=4时,它有5个划分:{4}、{3,1}、{2,2}、{2,1,1}、{1,1,1,1};

注意:4=1+3和4=3+1被认为是同一个划分。

该问题是求出n的所有划分个数,即f(n,n)。下面我们考虑求f(n,m)的方法。

解决方法:

根据n和m的关系,考虑下面几种情况:
(1)当n=1时,不论m的值为多少(m>0),只有一种划分,即{1};

(2)当m=1时,不论n的值为多少(n>0),只有一种划分,即{1,1,....1,1,1};

(3)当n=m时,根据划分中是否包含n,可以分为两种情况:

(a)划分中包含n的情况,只有一个,即{n};

(b)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分;

因此,f(n,n) = 1 + f(n, n - 1)。

(4)当n<m时,由于划分中不可能出现负数,因此就相当于f(n,n);

(5)当n>m时,根据划分中是否包含m,可以分为两种情况:

(a)划分中包含m的情况,即{m,{x1,x2,x3,...,xi}},其中{x1,x2,x3,...,xi}的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分个数为f(n-m, m);

(b)划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n, m - 1);

因此,f(n,m) = f(n - m,m) + f(n, m - 1)。

综合以上各种情况,可以看出,上面的结论具有递归定义的特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,而情况(5)为通用情况,属于递归的方法,其本质主要是通过减少n或m以达到回归条件,从而解决问题。

其递归表达式如下所示。

image

参考:http://blog.csdn.net/u011889952/article/details/44813593

/* https://www.nowcoder.com/practice/376537f4609a49d296901db5139639ec?
tpId=40&tqId=21339&tPage=1&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking
 简单以上题为例子,实际该题目有更优解法。
 f()函数是利用数组存值的递归函数,一定程度上减少了堆栈开销。
 f2()函数动态规划由小到大计算数组,在f()的基础上进一步减少了开销。*/
#include<iostream>
#include<math.h>
#define ROW 1000001
#define COL 20
using namespace std;
int record[ROW][COL];
void init(){
    for (int i = 0; i < COL; i++){
        for (int j = 0; j < ROW; j++){
            record[j][i] = 0;
        }
    }
    for (int i = 0; i < COL; i++){
        record[1][i] = 1;
    }
    for (int i = 0; i < ROW; i++){
        record[i][0] = 1;
    }
}
int f(int n, int m){
    if (n == 1 || m == 0){
        return 1;
    }
    int temp = pow(2, m);
    if (n == temp){
        if (record[n][m] == 0){
            record[n][m] = (f(n, m - 1) + 1) % 1000000000;
        }
    }
    else if (n > temp){
        if (record[n][m] == 0){
            record[n][m] = (f(n, m - 1) + f(n - temp, m)) % 1000000000;
        }
    }
    else if (n < temp){
        if (record[n][m] == 0){
            record[n][m] = (f(n, m - 1)) % 1000000000;
        }
    }
    return record[n][m] ;
}
int f2(int n, int m){
    for (int i = 1; i <= n; i++){
        for (int j = 0; j <= m; j++){
            if (i == 1 || j == 0){
                record[i][j] = 1;
            }
            int temp = pow(2, j);
            if (i == temp){
                record[i][j] = (record[i][j - 1] + 1) % 1000000000;
            }
            else if (i > temp){
                record[i][j] = (record[i][j - 1] + record[i - temp][j]) % 1000000000;
            }
            else if (i < temp){
                record[i][j] = (record[i][j - 1]) % 1000000000;
            }
        }
    }
    return record[n][m];
}
int main(){
    int n;
    cin >> n;
    init();
    int m = log10(n) / log10(2);
    cout <<f2(n, m) << endl;
    return 0;
}
  • 大整数
  1. 大数相加

输入包括两个数a和b,其中a和b的位数不超过1000位。输出a+b的值。
输入:
10000000000000000000 10000000000000000000000000000000
输出:
10000000000010000000000000000000

// 将加法的输入和输出存放在string中,逐位计算求解。
// 代码尽量再优化。
#include<iostream>
#include<string>
using namespace std;
int main(){
    string a, b;
    int result[10001];
    cin >> a >> b;

    int num = 0;
    int i = a.size() - 1, j = b.size() - 1;
    int k = 0;
    while (i >= 0 && j >= 0){
        result[k] = (int)(a[i] - '0' + b[j] - '0') + num;
        if (result[k] >= 10){
            result[k] %= 10;
            num = 1;
        }
        else{
            num = 0;
        }
        i--;
        j--;
        k++;
    }
    while (i >= 0){
        result[k] = (int)(a[i] - '0') + num;
        if (result[k] >= 10){
            result[k] %= 10;
            num = 1;
        }
        else{
            num = 0;
        }
        i--;
        k++;
    }
    while (j >= 0){
        result[k] = (int)(b[j] - '0') + num;
        if (result[k] >= 10){
            result[k] %= 10;
            num = 1;
        }
        else{
            num = 0;
        }
        j--;
        k++;
    }
    for (int index = k - 1; index >= 0; index--){
        cout << result[index];
    }
    cout << endl;
    return 0;
}

https://www.nowcoder.com/practice/4c39c984ea3848b48e111b8e71ec1dd4?tpId=40&tqId=21541&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking

  1. 大数阶乘

输入一个正整数N(<1000),输出N的阶乘。
输入:
15
输出:
1307674368000

// 将每次乘法的结果存放在int数组中,数组每个元素保存4位数。
#include<iostream>
#include<iomanip>
using namespace std;
int result[1000];
int size=1;
void mult(int b){
    int carry = 0;
    for (int i = 0; i < size; i++){
        result[i] = result[i] * b + carry;
        if (result[i] >= 10000){
            carry = result[i] / 10000;
            result[i] %= 10000;
        }
        else{
            carry = 0;
        }
    }
    if (carry != 0){
        result[size] = carry;
        size++;
    }
}
int main(){
    int n;
    cin >> n;
    result[0] = 1;
    for (int i = 1; i <= n; i++){
        mult(i);
    }
    for (int i = size - 1; i >= 0; i--){
        if (i == size-1){
            cout << result[i];
        }
        else{
            cout << setw(4) << setfill('0') << result[i];
        }
    }
    cout << endl;
    return 0;
}
// 使用JAVA中的BigInteger类
// add()  substract()  multiply()   divide() 对应加减乘除
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        BigInteger result = new BigInteger("1");
        for(int i=1;i<=n;i++){
            BigInteger temp = new BigInteger(i+"");
            result = result.multiply(temp);
        }
        System.out.println(result);
    }
}

https://www.nowcoder.com/practice/f54d8e6de61e4efb8cce3eebfd0e0daa?tpId=40&tqId=21355&tPage=2&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容

  • 第二章抓住特征研究整除 掌握分类熟练运用 这一章主要研究在整除的情况下,研究能被2、3、5整除数的特征;研究约数、...
    朝花夕拾杯中酒123阅读 876评论 1 8
  • 第一章数和数的运算 一概念 (一)整数 1整数的意义 自然数和0都是整数。 2自然数 我们在数物体的时候,用来表示...
    meychang阅读 2,571评论 0 5
  • 20170727搜狐面试算法实习生 岗位搜狐后台开发(机器学习NLP)10:00--11:101、首先自我介绍,b...
    minningl阅读 651评论 0 1
  • 文/秋枳 今天聊一下新近火热的童话剧——《美女与野兽》。 上映当天,C城依旧是无休止的雨天,似乎也没有要停歇的意思...
    秋枳阅读 418评论 1 0
  • 端午节作为四大传统节日之一,节日的气氛自当异常浓烈。关于端午,好像有永远讨论不完的话题,今天总结一下关于端午那些事...
    Joyful_Cheung阅读 267评论 4 2