大數問題(合輯)

來源:互聯網
上載者:User

標籤:acm   大數   

今天給學弟學妹們講大數問題,自己又把大數問題好好的複習了一遍,用c重新實現了一下;除法還是有點複雜,有點沒搞清,所以就不誤人子弟了,把大數的加法,乘法,減法,階乘都自己寫了一遍,對大數問題又加深了一點,大精度的還是要慢慢的積累,java版本的上次已經寫了;加一個自己的傳送門;java寫真的是挺方便的啊;java大數

一些基礎資料型別 (Elementary Data Type)的範圍:

int:32位整數,佔4位元組,-2^31~2^31-1(-21億多~21億多)
unsigned int:佔4位元組,0~2^32-1(0~42億多) –10位元

VC的64位整數 :
__int64:佔8位元組,-2^63~2^63-1(-900億億多~900億億多)
unsigned __int64:佔8位元組,0~2^64-1(0~1800億億多)-20位元
G++的64位整數:
long long==__int64
unsigned long long==unsigned __int64

實數
float:佔4位元組,7位有效數字
double:佔8位元組,15位有效數字
浮點型的問題都是追求精度的,在一般情況下我們應當選擇使用double,而很少用float;

所以當我們要進行計算的數超過了20位,我們就要用數組來類比我們的計算過程了;

選取的是poj百練上的比較基礎的例題,從基礎的開始做,只要弄懂就好,積累自己的模板,再靈活運用;


2981:大整數加法   http://bailian.openjudge.cn/practice/2981
其實大整數的加法之類的,演算法都比較簡單,按照我們平時豎式計算的方式,用數組類比大數的加法,要注意的就是處理好之間的進位問題,然後其中的輸入輸出也要注意,轉化成我們習慣的那種方式去進行計算,輸出的時候要處理好前端零; 主要是要理解這種處理方式; 下面是代碼:代碼就是隨便寫一下的,還可以進行最佳化,並不是最簡的,能夠易於理解就好;
#include <cstdio>#include <cstring>char a[220],b[220];int c[220],d[220];int result[240];int main(){    int i=0,j=0,lena,lenb,n;    gets(a);//把數字用字串儲存輸入    gets(b);    memset(c,0,sizeof(c));//對數組進行初始化    memset(d,0,sizeof(d));    memset(result,0,sizeof(result));    lena=strlen(a);    lenb=strlen(b);    n=lena>lenb?lena:lenb;    for(j=0,i=lena-1;i>=0;i--)//把字元數組倒序轉換到數字數組中(滿足我們的計算習慣)        c[j++]=a[i]-'0';    for(j=0,i=lenb-1;i>=0;i--)        d[j++]=b[i]-'0';    for(i=0;i<n;i++)    {     result[i]+=c[i]+d[i];//把兩個數組相加      if(result[i]>=10)//處理進位       {           result[i+1]++;           result[i]-=10;       }    }    i=n;    int flag=0;    while(!result[i])//處理前端零    {        if(i==0)        {            flag=1;            printf("0");        }        i--;    }    while(i>=0&&flag==0)    {        printf("%d",result[i]);        i--;    }    printf("\n");    return 0;}

2980:大整數乘法  http://bailian.openjudge.cn/practice/2980
乘法和加法的思想基本上一致,這裡要注意的是,i和j位置相乘的結果要儲存在結果數組的i+j的位置;下面是代碼;
#include <cstdio>#include <cstring>char a[220],b[220];int c[220],d[220];int result[440];int main(){    int i=0,j=0,lena,lenb,n;    gets(a);//把數字用字串儲存輸入    gets(b);    memset(c,0,sizeof(c));//對數組進行初始化    memset(d,0,sizeof(d));    memset(result,0,sizeof(result));    lena=strlen(a);    lenb=strlen(b);    n=lena>lenb?lena:lenb;    for(j=0,i=lena-1;i>=0;i--)//把字元數組倒序轉換到數字數組中(滿足我們的計算習慣)        c[j++]=a[i]-'0';    for(j=0,i=lenb-1;i>=0;i--)        d[j++]=b[i]-'0';    for(i=0;i<lena;i++)        for(j=0;j<lenb;j++)        result[i+j]+=c[i]*d[j];//i*j的結果要儲存在i+j的位置    for(i=0;i<n*2;i++)    {        if(result[i]>=10)//處理進位        {            result[i+1]+=result[i]/10;            result[i]%=10;        }    }    i=n*2-1;    while(result[i]==0) i--; //處理前端零    while(i>=0)    {         printf("%d",result[i]);         i--;    }    return 0;}

2736:大整數減法   http://bailian.openjudge.cn/practice/2736
減法和加法的思想基本一致;把程式中的加法換成減法,進位處理的時候注意; 下面是代碼;
#include <cstdio>#include <cstring>int main(){    //freopen("1.txt","r",stdin);    char a[220],b[220];    int c[220],d[220];    int result[240];    int n,i,j,lena,lenb;    scanf("%d",&n);    while(n--)    {        scanf("\n%s",a);        getchar();        scanf("%s",b);        memset(c,0,sizeof(c));        memset(d,0,sizeof(d));        memset(result,0,sizeof(result));        lena=strlen(a);        lenb=strlen(b);        for(i=lena-1,j=0;i>=0;i--)           c[j++]=a[i]-'0';        for(i=lenb-1,j=0;i>=0;i--)           d[j++]=b[i]-'0';        for(i=0;i<lena;i++)            result[i]=c[i]-d[i];        for(i=0;i<lena;i++)            if(result[i]<0)//處理小於零的情況            {                result[i]+=10;//向前一位借10;                result[i+1]--;            }      for(i=lena-1;!result[i]&&i>0;i--);//處理前端零      for(j=i;j>=0;j--)       printf("%d",result[j]);      printf("\n");    }    return 0;}

大數階乘: http://acm.nyist.net/JudgeOnline/problem.php?pid=28 大數階乘這裡就相當於進行了多次乘法,這裡我是用的10000進位,基本思想也是一樣的; 下面是代碼:
#include <cstdio>#include <cmath>void factorial(int n){int a[10000];int i,j,c,m=0;a[0]=1;for(i=1;i<=n;i++){    c=0;    for(j=0;j<=m;j++)//m表示的是當前數組的位元    {        a[j]=a[j]*i+c;        c=a[j]/10000;//判斷有沒有進位        a[j]=a[j]%10000; //儲存進位的數    }    if(c>0) {m++;a[m]=c;}}   printf("%d",a[m]);   int w=m*4+log10(a[m])+1;//這裡是計算階乘的總位元 (這裡可以不要)   for(i=m-1;i>=0;i--)      printf("%0.4d",a[i]);//假如當前位置的數沒滿4位的話,在前補零    printf("\n");    printf("%d",w);//(也可以不要這個輸出)}int main(){    int m;    while(scanf("%d",&m)!=EOF)    {        factorial(m);    }    return 0;}

大數除法還要自己去研究一下~研究好了再更新~









大數問題(合輯)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.