多少步得到回文数?

链接:https://ac.nowcoder.com/acm/contest/19859/G
来源:牛客网

题目描述

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。

例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87:
STEP1:87+78 = 165 STEP2:165+561 = 726

STEP3:726+627 = 1353 STEP4:1353+3531 = 4884

在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。

写一个程序,给定一个N(2<=N<=10或N=16)进制数M(100位之内),求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”
进制N>10时,使用大写’A’字母表示10,'B’表示11,…,'E’表示15

输入描述:
两行,分别为N,M
输出描述:
STEP=ans
示例1
输入
9
87
输出
STEP=6

解决方案

#include<stdio.h>
#include<string.h>
int judge(int sm[],int l)
{
    int i,j;
    for(i=0,j=l;i<=l;i++,j--)
    {//首尾相等的数就是回文数
        if(sm[i]!=sm[j])//但凡有一对不相等就不是
            return 1;
    }
    return 0;
}
int main()
{
    int n;
    scanf("%d\n",&n);//输入该数的进制
    char s[110];
    scanf("%s",s);//该数在100位之内,较大,以字符串形式输入
    int len=strlen(s);//计算长度
    int m[110]={0};
    int i,j,k,l=0;
    for(i=0;i<len;i++)
    {//将该数的每一位存入整形数组中,其中>='A'的数要转为整形
        if(s[i]>='A')
            m[i]=s[i]-'A'+10;
        else
            m[i]=s[i]-'0';
    }
    int sm[220]={0},cnt=0;
    for(k=0;k<30;k++)//三十次得不到回文数就不可能,因此设置范围三十次循环
    {
        if(cnt!=0)
        {//步数不为零,且没有break退出循环说明没得到回文数,将上一非回文数赋回m[]中,继续判断
            for(i=0;i<=l;i++)
                m[i]=sm[i];
            len=l+1;//此时的m数组长度为上一非回文数的长度,由于i=l时为上一非回文数数组的最后一位,所以长度要加一
        }
        for(i=0,j=len-1;i<len;i++,j--)
            sm[i]=m[i]+m[j];//数组首尾相加就是从左向右读与从右向左读的结果
        for(i=0;i<210;i++)//注意要小于数组长度,否则会越界
        {
            if(sm[i]>=n)
            {//进制为n,那么逢n进1
                sm[i+1]+=sm[i]/n;//不知道逢了多少n就除n,是sm[i+1]进
                sm[i]%=n;//进不了位的留在sm[i]中
            }
        }
        for(l=210;l>=0;l--)
        {//找到sm数组末尾那个数(因为是倒着存入数组,所以末位不为零)注意这里l要小于数组长度,否则会越界,就无法判断
            if(sm[l]!=0)
                break;//此时的l就是sm当前的长度
        }
        if(judge(sm,l))//判断sm是不是回文数
            cnt++;//不是的话,步数加一
        else
            break;//是的话退出循环
    }
    if(cnt>=30)
        printf("Impossible!");//如果判断了30次还没得到那么不可能
    else
        printf("STEP=%d",cnt+1);//因为最后一步没有cnt++,所以手动加一
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值