1620 - 火星A+B

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 32 MB

读入两个不超过25位的火星正整数AB,计算A+B。需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数。例如:地球上的10进制数2,在火星上记为“1,0”,因为火星个位数是2进制的;地球上的10进制数38,在火星上记为“1,1,1,0”,因为火星个位数是2进制的,十位数是3进制的,百位数是5进制的,千位数是7进制的……

题目输入

测试输入包含若干测试用例,每个测试用例占一行,包含两个火星正整数AB,火星整数的相邻两位数用逗号分隔,AB之间有一个空格间隔。当AB0时输入结束,相应的结果不要输出。

题目输出

对每个测试用例输出1行,即火星表示法的A+B的值。

输入/输出样例

输入格式

3,2,0 1,2,0
0 0

输出格式

1,0,1,0

C语言解答

/*
题目描述

读入两个不超过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的值。

样例输入

3,2,0 1,2,0
0 0

样例输出

1,0,1,0



  1,1,1,1,1,1 3,2,1,1

*/

//先将输入转译成两个数组
//再通过给定的运算法则进行计算
	//while
	//对每一位进行三项操作:加上进位项,相加,判断是否进位,
//输出

//疑难:如何进行位的对齐操作?有没有可能进位超过1?
#include <stdio.h>
#include <string.h>

int isZ(int a) //判断a是否为质数
{
	int i;
	
	for (i = 2; i < a; ++i) //可以再精简一些。。
	{
		if (a % i == 0) return 0;
	}
	return 1;
}
void getZ(int z[], int n)
{
	int i;
	int cnt;

	cnt = 0;
	for (i = 2; cnt < n; ++i)
	{
		if (isZ(i))
		{
			z[cnt++] = i;
		}
	}

}
int getA(int a[], int n, char flag) //如果得到的值为0,返回0 ,否则返回长度//0,0,0算是零么?
{
	int i = 0;
	int z = 1; //判断a是否为zero


	do {
		scanf("%d",a+i);
		if (a[i] != 0)
		{
			z = 0;
		}
		++i;
	}while(getchar() != flag && i < n); 

	if (z) return 0;

	return i; //默认i不可能为零
}

void add(int a[], int n1, int b[], int n2, int sum[]) //getSum的子函数,将a,b的各位加到sum,但不进位
{
	int i, j;

	for (i = 0; i < (n1 - n2); ++i)
	{
		sum[i] = a[i];
	}

	for (i = (n1 - n2), j = 0; i < n1; ++i, ++j)
	{
		sum[i] = a[i] + b[j];
	}

}
void verse(int a[], int n)//getSum子函数,将sum转置,使得sum从左到右位数变大
{
	int i;
	int temp;

	for (i = 0; i < n / 2; i++)
	{
		temp = a[i];
		a[i] = a[n - 1 - i];
		a[n - 1 - i] = temp;
	}
}
int getSum(int a[], int n1, int b[], int n2, int sum[], int z[]) //进行计算,返回结果的位数
{
	int i;
	int n;
	int c;

	n1 > n2 ? add(a,n1,b,n2,sum) : add(b,n2,a,n1,sum);//先把a,b的各个位加起来放到sum

	n = n1 > n2 ? n1 : n2; //得到当前sum的长度

	verse(sum, n);//将sum转置

	c = 0;
	for (i = 0; i < n || c > 0; ++i)//再对sum进行进位
	{
		sum[i] += c;
		c = 0;
		if (sum[i] >= z[i])
		{
			c = sum[i] / z[i];
			sum[i] %= z[i];
		}
	}
	
	return i; //i 就是sum的长度。i可能大于n
}

void out(int sum[], int n) //输出
{
	int i;

	for (i = n - 1; i >= 0; --i)
	{
		printf("%d", sum[i]);

		if (i != 0)
		{
			printf(",");
		}
		else
		{
			printf("\n");
		}

	}
}


int main(void)
{
	
	int z[30]; //质数序列
	int a[30], b[30]; //两个加数,两个数为左对齐
	int sum[30];		//和

	int n1, n2;		//两个加数的长度
	int n;			//和的长度

	memset(z,0, sizeof(z));
	getZ(z, 30);

	while (1)
	{
		//初始化
		memset(a, 0, 30 * sizeof(int));
		memset(b, 0, 30 * sizeof(int));
		memset(sum, 0, 30 * sizeof(int));

		n1 = n2 = n = 0;

		n1 = getA(a, 30, ' ');
		n2 = getA(b, 30, '\n');

		if (n1 == 0 && n2 == 0) break; //TODO 这里可能是&& 也可能是||

		n = getSum(a, n1, b, n2, sum, z);

		out(sum, n);

	}

	return 0;



}
/*
1,1,1,1,1,2,3,4,234,5,2,43,23,23,1,1,1,12,43,2134,234,23,5,5,5 1,34,5,34,5,56,34,23,1,2,3,4,5,6,45,4,4,5,7,6,54,3
1,1,1,1,1,1 23,2,3,4,34,2,3,23,23,4 2,345,34,2,3,4,4,5,3,2,2
34,5,56,7,65,45,34 234,34,5,5,6,54,4,4,4,5,4,3
0 1
*/



C++解答

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 30

int prime[N];

class Mars {
public:
    Mars() {
        memset(a, 0, sizeof(a));
        n = 1;
    }
    void init(char *s) {
        vector < int > v;
        int len = strlen(s), x = 0;
        for (int i = 0; i < len; ++i)
            if (s[i] != ',') {
                x = x * 10 + (s[i] - '0');
            } else {
                v.push_back(x);
                x = 0;
            }
        v.push_back(x);
        memset(a, 0, sizeof(a));
        n = v.size();
        for (int i = 0; i < n; ++i)
            a[i] = v[n - 1 - i];
    }
    bool isZero() {
        return 1 == n && 0 == a[0];
    }
    void writeln() {
        for (int i = n - 1; i > 0; --i)
            printf("%d,", a[i]);
        printf("%d\n", a[0]);
    }
    Mars operator + (const Mars & b) {
        Mars ret;
        ret.n = max(n, b.n);
        for (int i = 0; i < ret.n; ++i) {
            ret.a[i] += a[i] + b.a[i];
            if (ret.a[i] >= prime[i]) {
                ret.a[i] -= prime[i];
                ++ret.a[i + 1];
            }
        }
        if (ret.a[ret.n]) ++ret.n;
        return ret;
    }
private:
    int a[N], n;
};

void init() {
    for (int i = 2, pn = 0; pn < N; ++i) {
        bool flag = true;
        for (int j = 0; j < pn && prime[j] * prime[j] <= i; ++j)
            if (i % prime[j] == 0) {
                flag = false;
                break;
            }
        if (flag)
            prime[pn++] = i;
    }
}

int main() {
    char sa[100], sb[100];
    Mars a, b, c;
    init();
    while (true) {
        scanf("%s %s", sa, sb);
        a.init(sa);
        b.init(sb);
        if (a.isZero() && b.isZero())
            break;
        c = a + b;
        c.writeln();
    }
    return 0;
}