九度OJ 题目1016:火星A+B

本文介绍了一种处理火星整数相加的算法,火星整数采用不同进制表示,对应于第n位的进制是第n个素数。文章详细解释了算法原理,并提供了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.题目描述:
    读入两个不超过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

二.题目分析

 刚看到这道题目,我真的是楞了,一心想着38为什么表示成1,1,1,0,真的是百思不得其解,在网上看到一些解题报告,看到了长整数相加...好吧,终于开窍了,我真的是想多了...确实,这是一道长整数加法,这样看来,题目并不难,但是一直WA,自己也测试了大数据,小数据,还是没有找到错误原因,哎,对于不能提供错误样例的评判系统,真的是让人抓狂,这也是我一直热爱USACO的原因。

 在此还是贴出我的不知道错因的错误代码,欢迎各位行家指正,不胜感激!先贴出来,以后在改正吧,今天已经找bug精疲力尽...

三.代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int prime[51];
int IsPrime(int x)
{
	  int i;
    if(x==0||x==1)
        return 0;
    if(x==2)
        return 1;

    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
            return 0;
    }
    return 1;
}
void Reverse(int *a,int an)
{
    int i,j,temp;
    for(i=0,j=an-1;i<j;i++,j--)
    {
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}
int add(int *a,int an,int *b,int bn,int *sum)
{
    int maxn=an>bn?an:bn,i=an,j=bn,temp;
    while(i<maxn)
    {
        a[i]=0;
        i++;
    }
    while(j<maxn)
    {
        a[j]=0;
        j++;
    }

    for(i=0;i<=maxn;i++)
        sum[i]=0;

    for(i=0;i<maxn;i++)
    {
		temp=sum[i];
        sum[i] =(temp+a[i]+b[i])%prime[i];
        sum[i+1]=((temp+a[i]+b[i])/prime[i])%prime[i+1];
    }

    if(sum[i]!=0)
        return maxn+1;
    return maxn;
}
int main()
{
    char str1[60],str2[60];
    int a[50],b[50],sum[51],i,j,an,bn,sn,cn=0,temp;

    freopen("1016.txt","r",stdin);

    for(i=2,j=0;j<51;i++)
    {
        if(IsPrime(i))
        {
            prime[j]=i;
            j++;
        }
    }


    while(1)
    {
        scanf("%s%s",str1,str2);

        if(strlen(str1)==1&&str1[0]=='0'&&strlen(str2)==1&&str2[0]=='0')
            break;

        an=0;i=0;
        while(1)
        {
            a[an]=0;
            while(str1[i]!=','&&str1[i]!='\0')
            {
                a[an] *=10;
                a[an] +=str1[i]-'0';
                i++;
            }
            an++;
            if(str1[i]=='\0')
                break;
            i++;
        }

        bn=0;i=0;
        while(1)
        {
            b[bn]=0;
            while(str2[i]!=','&&str2[i]!='\0')
            {
                b[bn] *=10;
                b[bn] +=str2[i]-'0';
                i++;
            }
            bn++;
            if(str2[i]=='\0')
                break;
            i++;
        }


        Reverse(a,an);
        Reverse(b,bn);

        sn=add(a,an,b,bn,sum);
        Reverse(sum,sn);

        for(i=0;i<sn-1;i++)
            printf("%d,",sum[i]);
        printf("%d\n",sum[i]);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值