- 题目描述:
-
读入两个不超过25位的火星正整数A和B,计算A+B。需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数。例如:地球上的10进 制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位 数是3进制的,百位数是5进制的,千位数是7进制的……
- 输入:
-
测试输入包含若干测试用例,每个测试用例占一行,包含两个火星正整数A和B,火星整数的相邻两位数用逗号分隔,A和B之间有一个空格间隔。当A或B为0时输入结束,相应的结果不要输出。
- 输出:
-
对每个测试用例输出1行,即火星表示法的A+B的值。
- 样例输入:
-
1,0 2,1 4,2,0 1,2,0 1 10,6,4,2,1 0 0
- 样例输出:
-
1,0,1 1,1,1,0 1,0,0,0,0,0
跟大数运算加法有点像,对于大数运算第一位都是10进制,在取值时,需要模10,在这里只要模上该位对应的素数就OK了。
先建一个30位的素数表,判断n是否素数时只需检查n是否能被1到sqrt(n)之间的素数整除,这些素数可以从表里取得。若n是素数则将其加到表里。
代码如下:
#include <iostream> #include <vector> #include <sstream> #include <cmath> #include <algorithm> using namespace std; string A,B; int p[30]; vector<int> a,b,c; void init(){ p[0] = 2; p[1] = 3; p[2] = 5; int c = 3; for(int i=6;c<30;i++){ bool flag = true; for(int j=0;p[j]<=sqrt(i)+1;j++){ if(i%p[j]==0){ flag = false; break; } } if(flag){ p[c] = i; c++; } } } void toInt(){ a.clear(); b.clear(); for(int i=0;i<A.length();i++){ if(A[i]==',') A[i]=' '; } for(int i=0;i<B.length();i++){ if(B[i]==',') B[i]=' '; } int v; istringstream sina(A); while(sina>>v){ a.push_back(v); } istringstream sinb(B); while(sinb>>v){ b.push_back(v); } reverse(a.begin(),a.end()); reverse(b.begin(),b.end()); } void getRes(){ c.clear(); int la = a.size(); int lb = b.size(); int v = 0, carry = 0; for(int i=0;i<(la>lb?la:lb);i++){ if(i>=la){ v = b[i] + carry; } else if(i>=lb){ v = a[i] + carry; } else{ v = a[i] + b[i] + carry; } c.push_back(v%p[i]); carry = v/=p[i]; if(i==(la>lb?la:lb)-1&&carry!=0){ c.push_back(carry); } } reverse(c.begin(),c.end()); for(int i=0;i<c.size();i++){ if(i==c.size()-1){ cout<<c[i]<<endl; break; } cout<<c[i]<<","; } } int main(int argc,char* argv[]){ init(); while(cin>>A>>B&&A!="0"&&B!="0"){ toInt(); getRes(); } return 0; }