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 }

 

posted @ 2013-06-06 09:27  TonyFang  阅读(325)  评论(0编辑  收藏  举报