zoukankan      html  css  js  c++  java
  • TOI2008 大数运算

    内容 :

    在大多數的程式語言中,一個整數通常只有32位元,就算是使
    用無號的整數,仍然最大只能表示232-1。若要表示一個大於232-1的
    整數該怎麼辦呢?答案就是採用大數。本題要求寫出一個大數運算的
    程式,可以對二個50位數以內的10進制非負整數作乘法或除法的運
    算。除法運算時,毋須考慮除數為0的情形,並僅需算出商數。

    输入说明 :

    第一行輸入一個字串,表示被乘數或被除數,其為一個50位數
    以內的10進制非負整數。 

    第二行輸入運算符號 * 或 /,分別表示乘法或除法運算。 

    第三行輸入一個字串,表示乘數或除數,其為一個50位數以內
    的10進制非負整數。當執行除法運算時,除數為正整數。

    输出说明 :


    印出運算結果。

    范例输入 :help

     
    12346587987654321 
    * 
    98765432123456789 
    12345678901234567890 
    / 
    1234567890 

    范例输出 :

    1219416097850959788293446112635269
    10000000001

    提示 :

     

    出处 :

    2008 TOI 研習營初選
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cmath>
      6 using namespace std;
      7 int max(int a,int b) {
      8     return a>b?a:b;
      9 }
     10 int min(int a,int b) {
     11     return a<b?a:b;
     12 }
     13 /*高精度整数的数据结构*/
     14 struct Huge {
     15     int num[10000];
     16     int len;
     17     char sign;
     18 };
     19 /*高精度正数除法的数据结构*/
     20 struct DivMod {
     21     struct Huge div;
     22     struct Huge mod;
     23 }; 
     24 /*清零,将st初始化为0*/
     25 struct Huge Init(void) {
     26     struct Huge st;
     27     st.sign='+';
     28     st.num[0]=0;
     29     st.len=1;
     30     return st;
     31 } 
     32 /*将init初始化为st,假设st中全部为数字*/ 
     33 struct Huge Init(const char *st) {
     34     struct Huge init;
     35     memset(init.num,0,sizeof(init.num));
     36     init.len=strlen(st);
     37     for(int i=0;i<=strlen(st)-1;i++)
     38         init.num[i]=st[strlen(st)-1-i]-'0';
     39     return init;
     40 } 
     41 /*将init初始化为n*/
     42 struct Huge Init(int n) {
     43     struct Huge init;memset(init.num,0,sizeof(init.num)); 
     44     init.len=0;
     45     while(n>0) {
     46         init.num[init.len++]=n%10;
     47         n/=10;
     48     }
     49     return init;
     50 }
     51 /*比较x与y的大小,返回:值为1,x>y;值为0,x==y;值为-1,x<y*/ 
     52 int CompareHuge(struct Huge x, struct Huge y) {
     53     int i;
     54     if (x.len>y.len) return 1;
     55     if (x.len<y.len) return -1;
     56     for (i=x.len-1;x.num[i]==y.num[i]&&i>=0;i--);
     57     if (i<0) return 0;
     58     else return (x.num[i]>y.num[i]?1:-1);
     59 } 
     60 /*交换两个数*/ 
     61 void swap(struct Huge &x,struct Huge &y) {
     62     struct Huge temp;
     63     temp=x;x=y;y=temp;
     64 }
     65 /*返回:x向左移动y位后的结果(y>0)多出的位数,填0.*/
     66 struct Huge LeftShift(struct Huge x, int y) { 
     67     int i; 
     68     if(CompareHuge(x,Init())==0) return x;
     69     x.len+=y;
     70     for (i=x.len-1;i>=y;i--) x.num[i]=x.num[i-y];
     71     for (;i>=0;i--) x.num[i]=0;
     72     return x;
     73 }
     74 /*返回:x向右移动y位后的结果(y>0)少的位数,丢弃.*/
     75 struct Huge    RightShift(struct Huge x, int y) {
     76     if(CompareHuge(x,Init())==0) return x;  
     77     for(int i=0;i<=x.len-y-1;i++) x.num[i]=x.num[i+y];
     78     if(x.len>y) x.len-=y;
     79     else x=Init();
     80     return x;
     81 }
     82 /*打印高精度整数print的内容*/
     83 void PrintHuge(struct Huge print) {
     84 if(print.sign=='-') cout<<print.sign;
     85     for(int i=print.len-1;i>=0;i--) cout<<print.num[i];
     86     cout<<endl;
     87 }
     88 /*加法运算,返回x+y*/
     89 struct Huge add(struct Huge x, struct Huge y) {
     90     struct Huge ans; memset(ans.num,0,sizeof(ans.num));
     91     ans.sign='+';
     92     ans.len=max(x.len,y.len);
     93     for(int i=0;i<ans.len;i++) {
     94         if (i<=x.len-1 && i<=y.len-1) 
     95             ans.num[i]+=x.num[i]+y.num[i];
     96         else { 
     97                if (i>x.len-1) ans.num[i]+=y.num[i];
     98             else ans.num[i]+=x.num[i];
     99         }
    100         if(ans.num[i]>=10) { 
    101             ans.num[i+1]++;
    102             ans.num[i]%=10;
    103         }
    104     } 
    105     if(ans.num[ans.len]>0) ans.len++;
    106     return ans; 
    107 }
    108 /*减法运算,返回x-y*/
    109 struct Huge sub(struct Huge x,struct Huge y) {
    110     struct Huge ans;memset(ans.num,0,sizeof(ans.num));
    111     if(CompareHuge(x,y)==0) return Init();
    112     if(CompareHuge(x,y)==-1) {
    113         ans.sign='-';
    114         swap(x,y);
    115     }
    116     ans.len=x.len;
    117     for(int i=0;i<ans.len;i++) {
    118         if (i<y.len) ans.num[i]+=x.num[i]-y.num[i];
    119         else ans.num[i]+=x.num[i];
    120         if (ans.num[i]<0) {ans.num[i+1]--;ans.num[i]+=10;}
    121     }
    122     int i;
    123     for(i=ans.len-1;ans.num[i]==0;i--); 
    124     ans.len=i+1;
    125     return ans;
    126 } 
    127 /*乘法运算,返回a*b*/
    128 /*高精度数据乘单精度数据(个位数)运算 */
    129 struct Huge multi(struct Huge x, int y) {
    130     struct Huge ans;
    131     memset(ans.num,0,sizeof(ans.num)); ans.sign='+';
    132     if (y==0) return Init(); 
    133     ans.len=x.len;
    134     for (int i=0;i<ans.len;i++) {
    135         ans.num[i]+=x.num[i]*y;
    136         if(ans.num[i]>=10) {
    137             ans.num[i+1]+=ans.num[i]/10;
    138             ans.num[i]%=10;
    139         }
    140     }
    141     if(ans.num[ans.len]>0) ans.len++;
    142     return ans;
    143 } 
    144 /*高精度数据乘高精度数据运算*/ 
    145 struct Huge multi(struct Huge x,struct Huge y) {
    146     struct Huge ans; 
    147     memset(ans.num,0,sizeof(ans.num)); ans.sign='+';
    148     ans.len=x.len;
    149     for(int i=0;i<y.len;i++)
    150         ans=add(ans,LeftShift(multi(x,y.num[i]),i));
    151     for(int i=0;i<ans.len;i++)
    152         if(ans.num[i]>=10) {
    153             ans.num[i+1]+=ans.num[i]/10;
    154             ans.num[i]%=10;
    155         }
    156     if(ans.num[ans.len]>0) ans.len++;
    157     return ans;
    158 }
    159 /*除法运算,返回 a/b与a%b*/
    160 struct DivMod divmod(struct Huge x,struct Huge y) {
    161     struct DivMod ans;int i,tmp;
    162     ans.div.sign='+';ans.mod.sign='+';
    163     ans.div=Init();
    164     ans.mod=Init();
    165     if(y.len>x.len) {
    166         ans.mod=x;
    167         return ans;
    168     }
    169     i=x.len-y.len;
    170     y=LeftShift(y,i);
    171     for(;i>=0;i--) {
    172         tmp=0;
    173         while(CompareHuge(x,y)>=0) x=sub(x,y),tmp++;
    174         ans.div=LeftShift(ans.div,1);
    175         ans.div.num[0]=tmp; 
    176         y=RightShift(y,1);
    177     } 
    178     ans.mod=x;
    179     return ans;
    180 }
    181 /*取商*/ 
    182 struct Huge Div(struct Huge x,struct Huge y) {
    183     struct DivMod ans=divmod(x,y);
    184     return ans.div;
    185 }
    186 /*主函数*/ 
    187 int main() {
    188     struct Huge a,b;
    189     char t1[1001],t2[1001],fh;
    190     a.sign='+',b.sign='+';
    191     while(scanf("%s\n%c\n%s\n",t1,&fh,t2)!=EOF) {
    192         a=Init(t1);
    193         b=Init(t2);
    194         if(fh=='*') PrintHuge(multi(a,b));
    195         if(fh=='/') PrintHuge(Div(a,b));
    196     } 
    197     return 0;
    198 }
  • 相关阅读:
    一些数学证明
    重头再来
    二次函数传参
    神经网络
    准备写点随笔了
    如何做出响应式的页面 (转)
    自适应,响应式,viewport总结
    edm邮件制作规范
    博客园blog模板整理
    git 常用的命令
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/TOI20082.html
Copyright © 2011-2022 走看看