每天一道编程题——Have Fun with Numbers

能力还是太差了再加上忙,这个题费了好久,最后也是部分通过,原因是unsigned long long类型的数据,当输入20位数时,也会溢出。so。。。。最后两个测试点没有过,我再想想怎么办。。。。心好塞喔~~~

题目摘自: 浙大PAT

Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with K <script type="math/tex" id="MathJax-Element-1">K</script> digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.
Input Specification:

Each input contains one test case. Each case contains one positive integer with no more than 20 digits.
Output Specification:

For each test case, first print in a line “Yes” if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or “No” if not. Then in the next line, print the doubled number.
Sample Input:

1234567899

Sample Output:

Yes
2469135798

部分通过的代码:

#include<stdio.h>
#include<math.h>
int main()
{
    int sep(unsigned long long int n, int a[]);
    void sort(int a[]);
    void compare(int a[],int b[],unsigned long long int dn,int d1,int d2);
    int a[20]={0},b[20]={0};  
    unsigned long long n,dn;
    int d1,d2;
    scanf("%llu",&n);
    dn=2*n;
    d1=sep(n,a);  //个十百....位分离
    d2=sep(dn,b);
    sort(a);    //将分离后的数字排序(从大到小)
    sort(b);
    compare(a,b,dn,d1,d2);  //对比每一位是否相等
    return 0;
}
int sep(unsigned long long int n, int a[])
{
    int i=0;
    for(;n!=0;)
    {
        a[i]=n%10;   //取余
        n=n/10;
        i=i+1;
    }
    return i;   //返回该数字的位数
}
void sort(int a[])
{
    int i,j,k,temp;
    for(i=0;i<20;i++)
    {
        k=i;
        for(j=i+1;j<20;j++)
        {
            if(a[k]<a[j]) 
                k=j;
        }
        temp=a[k];a[k]=a[i];a[i]=temp;

    }
}
void compare(int a[],int b[],unsigned long long int dn,int d1,int d2)
{
    int i,tag=0;
    for(i=0;i<20;i++)
    {
        if(a[i]!=b[i])
            tag++;
    }
    if(tag==0 && d1==d2)
    {
        printf("Yes\n");
        printf("%llu\n",dn);
    }else
    {
        printf("No\n");
        printf("%llu\n",dn);
    }
}

当输入满的时候,测试点就过不去了,不知道该怎么办,有没有人会啊T T哭….

参考了网上的答案,用整型或者无符号整型存储这个超大数都会溢出,所以应该使用字符串来存储这个所谓的“超大数”,再将其转化为整型,在数组里进行加法运算(这里参考了别人的代码),最后的和我之前的方法一样,将它们排序,一一比较就好啦。

#include<stdio.h>
#include<math.h>
#include<string.h>
int db(int d1, int b[],int a[]);
void ToDigit(char n[] ,int d1,int a[]);
void sort(int a[]);
void compare(int tag,int d1,int a[],int b[],int c[]);

int main()
{


    char n[20];   
    int a[20]={0},b[20]={0},c[20]={0}; 
    int d1,d2,tag,i;    
    gets(n);
    d1=strlen(n);
    ToDigit(n,d1,a); //转化字符串数组为整型数字
    tag=db(d1,b,a);  // 将输入的数字乘2,如果乘2后位数增加,返回1否则返回0
    for(i=0;i<20;i++)
        c[i]=b[i];  //c存储未排序之前的double a
    sort(a);
    sort(b);
    compare(tag,d1,a,b,c);
    return 0;
}




void ToDigit(char n[] ,int d1,int a[])
{
    int i;
    for(i=0;i<d1;i++)
    {
        a[i]=n[i]-'0';
    }
}


int db(int d1, int b[],int a[])
{
    int i,tag=1;
    for(i=0;i<d1;i++)
        b[i]=2*a[i];
    for(i=d1-1;i>0;i--)
    {
        b[i-1]=b[i-1]+b[i]/10;
        b[i]=b[i]%10;
    }
    if(b[0]>9)
        return tag; 
    else
        return 0;
}


void sort(int a[])
{
    int i,j,k,temp;
    for(i=0;i<20;i++)
    {
        k=i;
        for(j=i+1;j<20;j++)
        {
            if(a[k]<a[j]) 
                k=j;
        }
        temp=a[k];a[k]=a[i];a[i]=temp;

    }
}
void compare(int tag,int d1,int a[],int b[],int c[])
{
    int i;
    for(i=0;i<20;i++)
    {
        if(a[i]!=b[i])
            tag++;
    }
    if(tag==0)
    {
        printf("Yes\n");
        for(i=0;i<d1;i++)
            printf("%d",c[i]);
    }else
    {
        printf("No\n");
        for(i=0;i<=d1;i++)
            printf("%d",c[i]);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值