【C】数学问题

1.组合数:

#include<stdio.h>
#include<iostream>
using namespace std;
long long res[67][67]={0};
long long C(int n,int m){
    if(m==0||n==m) return 1;
    if(res[n][m]!=0) return res[n][m];
    return res[n][m]=C(n-1,m)+C(n-1,m-1);
}
int main(){
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF){
        cout<<C(n,m)<<endl;
    }
    return 0;
}

2.扩展欧几里得算法

//ax+by=gcd(a,b)
#include<stdio.h>
#include<iostream>
using namespace std;
int exgcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;
        return a;
    }
    int g=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return g;//g是gcd
}
int main(){
    int a,b;
    while(scanf("%d %d",&a,&b)!=EOF){
        int x=0,y=0;
        int g=exgcd(a,b,x,y);
        printf("%dx+%dy=%d的解是:x=%d,y=%d\n",a,b,g,x,y);
    }
    return 0;
}
//ax+by=c
#include<stdio.h>
#include<iostream>
using namespace std;
int exgcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;
        return a;
    }
    int g=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return g;//g是gcd
}
int main(){
    int a,b,c;
    while(scanf("%d %d %d",&a,&b,&c)!=EOF){
        int x=0,y=0;
        int g=exgcd(a,b,x,y);
        if(c%g!=0) printf("%dx+%dy=%d无整数解\n",a,b,c);
        else{
            int x1=x*c/g,y1=y*c/g;
            printf("%dx+%dy=%d的解是:x=%d,y=%d\n",a,b,c,x1,y1);
            //kx=b/gcd,ky=-a/gcd;  
            //解集为:(x1+kx*t,y1+ky*t)t为整数 
        }
    }
    return 0;
}
//ax≡c(mod b)
#include<stdio.h>
#include<iostream>
using namespace std;
int exgcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;
        return a;
    }
    int g=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return g;//g是gcd
}
int main(){
    int a,b,c;
    while(scanf("%d %d %d",&a,&b,&c)!=EOF){
        int x=0,y=0;
        int g=exgcd(a,b,x,y);
        if(c%g!=0) printf("%dx%d(mod)%d 无解\n",a,c,b);
        else{
            int x1=x+b/g;
            printf("%dx%d(mod)%d 的解是:x=%d\n",a,c,b,x1);
            //解集:x+b/g*k(k=0,1,2,...,g-1)
        }
    }
    return 0;
}

3.大数

//大数排序
#include<stdio.h>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<string>
using namespace std;
struct bign{
    char d[1010];
    int len;
}num[110];
bool cmp(bign a,bign b){
    if(a.len!=b.len) return a.len<b.len;
    for(int i=0;i<a.len;i++){
        if(a.d[i]!=b.d[i]) return a.d[i]<b.d[i];
    }
    return true;
}
void print(bign a){
    for(int i=0;i<a.len;i++){
        cout<<a.d[i];
    }
    cout<<endl;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        getchar();
        for(int i=0;i<n;i++){
            string str;
            getline(cin,str);
            num[i].len=str.size();
            for(int j=0;j<str.size();j++){
                num[i].d[j]=str[j];
            }
        }
        sort(num,num+n,cmp);
        for(int i=0;i<n;i++){
            print(num[i]);
        }
    }
    return 0;
}

问题 F: 10进制 VS 2进制
时间限制: 1 Sec 内存限制: 32 MB
提交: 36 解决: 21
[提交][状态][TK题库][命题人:]
题目描述
对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们称B为A的二进制逆序数。
例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。
输入
一个1000位(即10^999)以内的十进制数。
输出
输入的十进制数的二进制逆序数。
样例输入
985
样例输出
623

//1000位以内十进制转换成二进制
#include<stdio.h>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<string>
using namespace std;
struct bign{
    int d[4010];
    int len;
};
void print(bign a){
    for(int i=0;i<a.len;i++){
        cout<<a.d[i];
    }
    cout<<endl;
}
bign divide(bign a,int b,int &r){//a/2,b=2
    bign c;
    c.len=a.len;
    for(int i=0;i<a.len;i++){
        r=r*10+a.d[i];
        if(r<b) c.d[i]=0;
        else{
            c.d[i]=r/b;
            r=r%b;
        }
    }
    int i=0;
    while(c.d[i]==0) i++;
    bign d;
    d.len=c.len-i;
    for(int j=0;j<d.len;j++){
        d.d[j]=c.d[i];
        i++;
    }
    return d;
}
bign multi(bign a,int b){
    int carry=0;
    bign c;c.len=0;
    for(int i=a.len-1;i>=0;i--){
        int temp=a.d[i]*b+carry;
        carry=temp/10;
        c.d[c.len++]=temp%10;
    }
    while(carry!=0){
        c.d[c.len++]=carry%10;
        carry/=10;
    }
    bign d;d.len=0;
    for(int i=c.len-1;i>=0;i--){
        d.d[d.len++]=c.d[i];
    }
    return d;
}
bign add(bign a,bign b){
    bign c;c.len=0;
    int carry=0;
    int i,j;
    for(i=a.len-1,j=b.len-1;i>=0&&j>=0;i--,j--){
        int temp=a.d[i]+b.d[j]+carry;
        c.d[c.len++]=temp%10;
        carry=temp/10;
    }
    while(i>=0){
        int temp=carry+a.d[i];
        c.d[c.len++]=temp%10;
        carry=temp/10;
        i--;
    }
    while(j>=0){
        int temp=carry+b.d[j];
        c.d[c.len++]=temp%10;
        carry=temp/10;
        j--;
    }
    if(carry!=0) c.d[c.len++]=carry;
    bign d;d.len=0;
    for(int i=c.len-1;i>=0;i--){
        d.d[d.len++]=c.d[i];
    }
    return d;
}
bign ten_two(bign a){//十进制转二进制,已经逆序:130=01000001
    bign c=a;
    bign tar;
    tar.len=0;
    while(c.len!=0){
        int r=0;
        c=divide(c,2,r);
        tar.d[tar.len++]=r;
    }
    return tar;
}
bign two_ten(bign a){//二进制转十进制
    bign d;
    d.len=1;d.d[0]=0;
    for(int i=0;i<a.len;i++){
        if(i!=a.len-1&&a.d[i]!=0){
            bign c;c.len=1;c.d[0]=1;
            int p=a.len-i-1;//i位置,2^p
            //cout<<p<<endl;
            while(p>0){
                c=multi(c,2);
                p--;
            }
            d=add(d,c);
        }
        else if(i==a.len-1&&a.d[i]==1){
            bign c;c.len=1;c.d[0]=1;
            d=add(d,c);
        }

    }
    return d;
}
int main(){
    string str;
    getline(cin,str);
    bign a;
    for(int i=0;i<str.size();i++){
        a.d[i]=(int)(str[i]-'0');
    }
    a.len=str.size();
    bign er=ten_two(a);
    //print(er);
    bign shi=two_ten(er);
    print(shi);
    return 0;
}

4.快速幂

//快速模幂,a^b%m
long long binarypow(long long a,long long b,long long m){
    if(b==0) return 1;
    if(b&1==1){//b%2==1
        return a*binarypow(a,b-1,m)%m;
    }
    else{
        long long mul=binary(a,b/2,m);
        return mul*mul%m;
    }
}

Raising Modulo Numbers
Time Limit: 1000MS

Memory Limit: 30000K
Total Submissions: 5499

Accepted: 3184
Description
People are different. Some secretly read magazines full of interesting girls’ pictures, others create an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games. Latest marketing research shows, that this market segment was so far underestimated and that there is lack of such games. This kind of game was thus included into the KOKODáKH. The rules follow:

Each player chooses two numbers Ai and Bi and writes them on a slip of paper. Others cannot see the numbers. In a given moment all players show their numbers to the others. The goal is to determine the sum of all expressions AiBi from all players including oneself and determine the remainder after division by a given number M. The winner is the one who first determines the correct result. According to the players’ experience it is possible to increase the difficulty by choosing higher numbers.

You should write a program that calculates the result and is able to find out who won the game.

Input
The input consists of Z assignments. The number of them is given by the single positive integer Z appearing on the first line of input. Then the assignements follow. Each assignement begins with line containing an integer M (1 <= M <= 45000). The sum will be divided by this number. Next line contains number of players H (1 <= H <= 45000). Next exactly H lines follow. On each line, there are exactly two numbers Ai and Bi separated by space. Both numbers cannot be equal zero at the same time.
Output
For each assingnement there is the only one line of output. On this line, there is a number, the result of expression
(A1B1+A2B2+ … +AHBH)mod M.
Sample Input
3
16
4
2 3
3 4
4 5
5 6
36123
1
2374859 3029382
17
1
3 18132
Sample Output
2
13195
13

//
#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long LL;
LL binaryPow(LL x,LL y,LL k){//x^y%k
    if(y==0) return 1;
    if(y&1==1) return x*binaryPow(x,y-1,k)%k;
    else{
        LL mul=binaryPow(x,y/2,k);
        return mul*mul%k;
    }
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int k,m;
        int sum=0;
        cin>>k>>m;
        for(int j=0;j<m;j++){
            int a,b;
            cin>>a>>b;
            sum=(sum+binaryPow(a,b,k))%k;
        }
        cout<<sum%k<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/li_jiaqian/article/details/79523567