luogu10125回文数[noip1999 Day1 T1]

 

题目描述

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

例如:给定一个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,M。

输出格式:

STEP=ans

输入输出样例

输入样例#1:
10
87
输出样例#1:
STEP=4

思路:暴力枚举30次,再仍上高精度加法(将mod 10 改成 mod N即可)。

 

注意事项:单纯思路有点简单了,说说要注意的地方吧,这题确实有一些地方会让人卡住。

1)注意读入后,将字符串数组转化为int型数组时,要考虑处理16进制数的情况,所以判断该字符是否是字母,若是,转化成10~15(16进制下的A~F)

2)最开始时要判断不需要头尾相加时就已经是回文数的情况。

#include<cstdio>
#include<cstring>
using namespace std;
int n,len,a[11111],b[11111],c[11111];
bool jud(int *X)
{
    for(int i=1;i<=len/2;i++)
        if(X[i]!=X[len-i+1])return 0;
    return 1;
}
void add_num()
{
    int x=0;
    for(int i=1;i<=len;i++){
        x+=a[i]+b[i];
        c[i]+=x%n;
        x/=n;
    }
    while(x){c[++len]=x%n;x/=n;}
}
void solve()
{
    if(jud(a)){puts("STEP=0");return;}
    for(int k=1;k<=30;k++){
        memset(c,0,sizeof(c));
        for(int i=1;i<=len;i++)
            b[i]=a[len-i+1];
        add_num();
        if(jud(c)){printf("STEP=%d\n",k);return;}
        for(int i=1;i<=len;i++)
            a[i]=c[i];
    }
    puts("Impossible!");
}
int main()
{
    char cr[111];
    scanf("%d%s",&n,cr);
    len=strlen(cr);
    for(int i=0;i<len;i++){
        if('0'<=cr[i]&&cr[i]<='9')
            a[len-i]=cr[i]-48;
        if('A'<=cr[i]&&cr[i]<='Z')
            a[len-i]=cr[i]-55;
    }
    solve();
    return 0;
}



 

posted @ 2016-08-28 22:12  keshuqi  阅读(300)  评论(0编辑  收藏  举报