1. 程式人生 > >數學問題-高精度運算

數學問題-高精度運算

include sed radi ide pri turn 模板 int post

模板:http://www.cnblogs.com/TQCAI/p/8410799.html


1.高精度加法訓練

技術分享圖片
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include 
<map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 10000 #define MAX 1<<30 #define V vector<int> #define ll long long using namespace std; typedef struct hp{
int len; char s[LEN]; hp(){ len=0; memset(s,0,LEN); } hp(const char *ch){ memset(s,0,LEN); len=strlen(ch); for(int i=0;i<len;i++){ s[len-i]=ch[i]-48; } } void print(){ for(int i=len;i>=1;i--){ putchar(s[i]
+48); } } }hp; hp add(const hp&a,const hp&b){ int i,len=max(a.len,b.len); hp c; for(i=1;i<=len;i++){ c.s[i]+=a.s[i]+b.s[i]; if(c.s[i]>9){ c.s[i+1]++; c.s[i]%=10; } } len++; while(len>1 && c.s[len]==0) len--; c.len=len; return c; } int main(){ // freopen("A+B Problem.txt","r",stdin); char a[LEN]; char b[LEN]; scanf("%s",a); scanf("%s",b); add(hp(a),hp(b)).print(); puts(""); return 0; }
View Code

註意0的特殊情況,以及用scanf讀入字符串而不能用gets讀入(gets會讀入空格)


2.高精度減法訓練

技術分享圖片
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1000000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            s[len-i]=ch[i]-48;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            putchar(s[i]+48);
        }
    }
}hp;

int compare(const hp&a,const hp&b){
    int len=max(a.len,b.len);
    while(len>0 && a.s[len]==b.s[len]) len--;
    if(!len) return 0;
    return a.s[len]-b.s[len];
} 

hp subtract(const hp&a,const hp&b){    //a 大 b小 
    int i,len=max(a.len,b.len);
    hp c;
    for(i=1;i<=len;i++){
        c.s[i]+=a.s[i]-b.s[i];
        if(c.s[i]<0){
            c.s[i+1]--;
            c.s[i]+=10;
        }
    }
    while(len>1 && c.s[len]==0) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("高精度減法.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%s",a);
    scanf("%s",b);
    int d=compare(a,b);
    if(d<0){
        printf("-");
        subtract(b,a).print();
    }
    else if(d>0) subtract(a,b).print();
    else puts("0");
    return 0; 
}
View Code

註意用compare函數進行大數的大小判斷。如果第一個比第二個小就b-a並且輸出負號


3.高精度乘法訓練

技術分享圖片
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            s[len-i]=ch[i]-48;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            putchar(s[i]+48);
        }
    }
}hp;

hp multiply(const hp&a,const hp&b) {
    int i,j,len=a.len+b.len+1;
    hp c;
    for(i=1;i<=a.len;i++){
        for(j=1;j<=b.len;j++){
            c.s[i+j-1]+=a.s[i]*b.s[j];
            c.s[i+j]+=c.s[i+j-1]/10;
            c.s[i+j-1]%=10;
        }
    } 
    while(len>1 && c.s[len]==0 ) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("A×B Problem.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%s",a);
    scanf("%s",b);
    multiply(hp(a),hp(b)).print();
    puts("");
    return 0; 
}
View Code

這題可以說很簡單,只要理解(或者熟背)高精度乘法板子,默寫下來就OK了。


靈活多變的題型:

1.B進制星球:

技術分享圖片
#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

int radix=10;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            if(ch[i]>=0 && ch[i]<=9)
                s[len-i]=ch[i]-0;
            else if(ch[i]>=A && ch[i]<=Z)
                s[len-i]=ch[i]-A+10;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            if(s[i]>=0 && s[i]<=9)
                putchar(s[i]+0);
            else
                putchar(s[i]-10+A);
        }
    }
}hp;

hp add(const hp&a,const hp&b){
    int i,len=max(a.len,b.len);
    hp c;
    for(i=1;i<=len;i++){
        c.s[i]+=a.s[i]+b.s[i];
        if(c.s[i]>=radix){
            c.s[i+1]++;
            c.s[i]%=radix;
        }
    }
    len++;
    while(len>1 && c.s[len]==0) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("D:\\CbWorkspace\\數學問題\\高精度\\B進制星球.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%d",&radix);
    scanf("%s",a);
    scanf("%s",b);
    add(hp(a),hp(b)).print();
    puts("");
    return 0; 
}
View Code

模擬其他進制的高精度運算。只要搞清楚10進制加法的進位原理,只要改一下radix參數就可以了。


數學問題-高精度運算