1. 程式人生 > 其它 >高精度計算問題

高精度計算問題

技術標籤:CCF

高精度加法

描述
求兩個不超過200位的非負整數的和。

輸入
有兩行,每行是一個不超過200位的非負整數,可能有多餘的前導0。
輸出
一行,即相加後的結果。結果裡不能有多餘的前導0,即如果結果是342,那麼就不能輸出為0342。
樣例輸入
22222222222222222222
33333333333333333333
樣例輸出
55555555555555555555

//題解:高精度入門題:結構體+字元轉換+進位 
#include<cstdio>
#include<cstring>
struct nod{int n,a[210];nod(){memset(
a,0,sizeof(a));}}a,b; char s[210]; int main() { int ns;//讀入a============ scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); a.n=ns; for(int i=1;i<=ns;i++)//字元逆序轉換為數字 {//為了數位 對齊,翻轉數字 a.a[ns-i+1]=s[i]-'0'; }//======================== //讀入b==================== scanf
("%s",s+1);//下標從1開始 ns=strlen(s+1); b.n=ns; for(int i=1;i<=ns;i++)//字元逆序轉換為數字 {//為了數位 對齊,翻轉數字 b.a[ns-i+1]=s[i]-'0'; }//========================= //模擬加法運算 a.n=a.n>b.n?a.n:b.n;//確定數位 for(int i=1;i<=a.n;i++)//暴力加 { a.a[i]+=b.a[i]; } for
(int i=1;i<=a.n;i++)//處理進位 { if(a.a[i]>9) { a.a[i+1]+=a.a[i]/10;//向右進位 a.a[i]%=10;//保留個位數 if(i==a.n) a.n++;//最高位溢位 } } //消除前導0 while(a.a[a.n]==0&&a.n>1) a.n--;//最高位必須非0 //反向輸出 for(int i=a.n;i>=1;i--) { printf("%d ",a.a[i]); } return 0; }

高精度減法

描述
求兩個大的正整數相減的差。

輸入
共2行,第1行是被減數a,第2行是減數b(a > b)。每個大整數不超過200位,不會有多餘的前導零。
輸出
一行,即所求的差。
樣例輸入
9999999999999999999999999999999999999
9999999999999
樣例輸出
9999999999999999999999990000000000000

//題解:高精度入門題:結構體+字元轉換+借位 
#include<cstdio>
#include<cstring>
struct nod{int n,a[210];nod(){memset(a,0,sizeof(a));}}a,b;
char s[210];
int main()
{
    int ns;//讀入a============ 
    scanf("%s",s+1);//下標從1開始 
    ns=strlen(s+1);    a.n=ns;
    for(int i=1;i<=ns;i++)//字元逆序轉換為數字 
    {//為了數位 對齊,翻轉數字 
        a.a[ns-i+1]=s[i]-'0';
    }//========================
    //讀入b==================== 
    scanf("%s",s+1);//下標從1開始 
    ns=strlen(s+1);    b.n=ns;
    for(int i=1;i<=ns;i++)//字元逆序轉換為數字 
    {//為了數位 對齊,翻轉數字 
        b.a[ns-i+1]=s[i]-'0';
    }//=========================
    //模擬減法運算  
    for(int i=1;i<=a.n;i++) a.a[i]-=b.a[i];//暴力減 
    for(int i=1;i<=a.n;i++)//處理借位 
    {
        if(a.a[i]<0)
        {
            a.a[i+1]-=1;//向右借 1 
            a.a[i]+=10;//補充數值 
        }
    }
    //消除前導0//本題保證a>b,如果不知道大小關係呢? 
    while(a.a[a.n]==0&&a.n>1) a.n--;//最高位必須非0
    //反向輸出
    for(int i=a.n;i>=1;i--) printf("%d",a.a[i]);
    return 0;
}

高精度乘法

高精度*低精度

描述
任意給定一個正整數N(N<=100),計算2的n次方的值。
輸入
輸入一個正整數N。
輸出
輸出2的N次方的值。
樣例輸入
5
樣例輸出
32

//題解:高精度*低精度 +非結構體 +函式 
#include<cstdio>
int a[1010],na;//估算陣列,2的100次不知道是多少位?
//10的100次是1000位,可以了嗎?
void cf(int x)
{
    for(int i=1;i<=na;i++)//每位都乘 
    {
        a[i]*=x;
    }
    for(int i=1;i<=na;i++)//處理進位 
    {
        if(a[i]>9)
        {
            a[i+1]+=a[i]/10;
            a[i]%=10;
            if(i==na) na++;//最高位溢位 
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    a[1]=1;na=1;
    for(int i=1;i<=n;i++)
    {
        cf(2);
    }
    for(int i=na;i>=1;i--) printf("%d",a[i]);//反向輸出 
    
    //現在你可以知道2的100次方是多少位了嗎? 
    
    return 0;
}
 

高精度除法

高精度/低精度

描述
已知正整數k滿足2<=k<=9,現給出長度最大為30位的十進位制非負整數c,求所有能整除c的k。

輸入
一個非負整數c,c的位數<=30。
輸出
若存在滿足 c%k == 0 的k,從小到大輸出所有這樣的k,相鄰兩個數之間用單個空格隔開;若沒有這樣的k,則輸出"none"。
樣例輸入
30
樣例輸出
2 3 5 6

//題解:高精度除以低精度:模擬思想 
#include<cstdio>
#include<cstring>
char s[210];
int a[210],na,ls=0; 
void chu(int x)
{
    int k=0;//餘數 
    for(int i=na;i>=1;i--)//模擬豎式除法 
    {
        k=k*10+a[i];
        k=k%x;
    }
    if(k==0) 
    {    ls=1; //打標籤 
        printf("%d ",x);
    } 
}
int main()
{
    int ns;
    scanf("%s",s+1);//下標從1開始 
    ns=strlen(s+1);    na=ns;
    for(int i=1;i<=ns;i++)//字元逆序轉換為數字 
    {
        a[ns-i+1]=s[i]-'0';
    }
    for(int i=2;i<=9;i++)
    {
        chu(i);//函式處理 
    }
    if(ls==0) printf("none"); 
    return 0;
}