1023 Have Fun with Numbers (20分)

参考柳神代码,柳神的代码写的也太秒了Orz。啊这明明是个\(20\)分的题,我为什么还要参考,菜的安详+_+ 。

题意

要求原数字乘\(2\)后的结果是原数字的一个重新排列,用\(cnt\)数组记录原数和新数的各位数字情况,最后只有\(cnt[1 \sim 9]\)全为0才代表新产生的数是原数的一个排列。

思路

首先,如果两个整数的长度不同,那么命题一定不成立,返回false;而当两个整数的长度相同时,可以开一个count数组,用来存放09中每个数字的出现次数。然后枚举两个整数的所有数位,对原整数中出现的数字,令对应的count值加1;对新整数中出现的数字,令对应的count值减1。如果在枚举完所有数位后,所有count数组元素的值均为0,说明新整数的数位是原整数数位的一个排列,返回true;只要09中有一个数字的出现次数不为0,则返回false。

代码

如果新产生的数的位数大于原数的位数即最高位仍然有进位,说明两个数的长度不同,也要输出\(No\)

const int N=25;
char s[N];
int a[N],b[N];
int cnt[10];
int n;

int main()
{
    scanf("%s",s);

    n=strlen(s);

    int t=0;
    for(int i=n-1;i>=0;i--)
    {
        a[i]=s[i]-'0';
        cnt[a[i]]++;
        
        int x=a[i]*2+t;
        b[i]=x%10;
        cnt[b[i]]--;
        t=x/10;
    }

    bool ok=true;
    for(int i=0;i<10;i++)
        if(cnt[i] != 0)
            ok=false;

    if(t || !ok) puts("No");
    else puts("Yes");

    if(t) cout<<1;
    for(int i=0;i<n;i++) cout<<b[i];
    cout<<endl;
    //system("pause");
    return 0;
}

当然,也可以用两个\(cnt\)数组分别记录,感觉更好理解一点。

const int N=25;
char s[N];
int a[N],b[N];
int cnta[10],cntb[10];
int n;

int main()
{
    scanf("%s",s);

    n=strlen(s);

    int t=0;
    for(int i=n-1;i>=0;i--)
    {
        a[i]=s[i]-'0';
        cnta[a[i]]++;

        int x=a[i]*2+t;
        b[i]=x%10;
        cntb[b[i]]++;
        t=x/10;
    }

    bool ok=true;
    for(int i=0;i<10;i++)
        if(cnta[i] != cntb[i])
            ok=false;
            
    if(t || !ok) puts("No");
    else puts("Yes");

    if(t) cout<<1;
    for(int i=0;i<n;i++) cout<<b[i];
    cout<<endl;
    //system("pause");
    return 0;
}
posted @ 2021-01-26 11:09  Dazzling!  阅读(67)  评论(0编辑  收藏  举报