火星A+B
Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11671 Accepted Submission(s): 3907
Problem Description
读 入两个不超过25位的火星正整数A和B,计算A+B。需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数。例如:地球上的10进制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位数 是3进制的,百位数是5进制的,千位数是7进制的……
Input
测试输入包含若干测试用例,每个测试用例占一行,包含两个火星正整数A和B,火星整数的相邻两位数用逗号分隔,A和B之间有一个空格间隔。当A或B为0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即火星表示法的A+B的值。
Sample Input
1,02,1
4,2,01,2,0
110,6,4,2,1
00
Sample Output
1,0,1
1,1,1,0
1,0,0,0,0,0
【思路分析】
解此题的关键在于对进制转换的理解,刚开始我对此题中N进制的理解只局限于我们日常生活中经常用的十进制,所以,我一开始的思路是先将给出的火星整数转换为我们所熟悉的十进制,然后在将两数相加,然后再将和转换为火星正整数,但是在做题的时候发现:将火星整数转换为十进制数是很难实现的,或者根本就没法实现,然后我再次读题,观察样例,发现,样例输出是有规律的,举个列子:
样例:4,2,0 1,2,0
答案:1,1,1,0
4,2,0
+1,2,0
—————
5,4,0
很显然5,4,0这个答案是错误的,为什么错了,因为我们是按的十进制算的,而按题目要求可以发现:4,2,0中0是第一位,所以进制应该第一个素数是:2,2是第二位,所以应该是第二个素数:3,4是第四位,所以进制应该是第3个素数:5,所以,5,4,0中的4应该进位变为1,而5应该加上由前面进位得来的1得6,然后发现又得进位,所以,最后答案就变成了1,1,1,0,按照这个思路,其他几个样例的答案的由来就简单多了,就不在多做解释了,具体代码实现见代码!
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <iomanip>
#include <stdio.h>
using namespace std;
int main()
{
string s1,s2;
int a[100], b[100], s[100];
int cnt = 0,flag,ch[25];
for(int i = 2; i < 100; i++)
{
flag = 0;
for(int j = 2; j < i; j++)
{
if(i % j == 0)
{
flag = 1;
break;
}
}
if(flag == 0)
ch[cnt] = i,
cnt++;
if(cnt == 25)
break;
}//找出前25个素数
while(cin >> s1 >> s2)
{
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
memset(s, 0, sizeof s);
int k = 0, l1 = 0, l2 = 0, maxlen = 0, minlen = 0, cnt = 0, ans = 0, t =0;
l1 = s1.length();
l2 = s2.length();
for(int i = 0; i < l1; i++)
{
if(s1[i] != ',')
a[cnt] = a[cnt] * 10 + (s1[i] -'0');
else if(s1[i] == ',')
cnt++;
}
for(int i = 0; i < l2; i++)
{
if(s2[i] != ',')
b[ans] = b[ans] * 10 + (s2[i] -'0');
else if(s2[i] == ',')
ans++;
}//字符串s1、s2装换为int型并存入数组a、b
if(cnt == 0 && ans == 0 && a[0] == 0 && b[0] ==0)
break;
for(int i = 0, j = cnt; i < j; i++, j--)
{
int mid = a[i];
a[i] = a[j];
a[j] = mid;
}
for(int i = 0, j = ans; i < j; i++, j--)
{
int mid = b[i];
b[i] = b[j];
b[j] = mid;
}//将数组a、b的类容倒置
maxlen = max(cnt, ans);
for(int i = 0; i <= maxlen; i++)
{
s[t] = k + a[i] + b[i];
if(s[t] >= ch[t])
{
s[t] = s[t] - ch[t];
k = 1;
t++;
}
else if(s[t] < ch[t])
{
k = 0;
t++;
}
}
if(k != 0)
s[t] = k;
else
t = t - 1;//判断最后一位是否有进位
for(int i = t; i >= 0; i--)
{
if(i > 0)
cout << s[i] <<",";
else if(i == 0)
cout << s[i] <<endl;
}
}
return 0;
}