题目描述

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加56(即把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,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”

输入描述:

两行,分别为N,M

输出描述:

STEP=ans

示例1

输入
9
87
输出
STEP=6

解答

需要注意的是,读入的数可能为16进制数。在这里我采用的是用一个数组来存储数字m的每一位,这样每次相加时,只需要将数组的顺序与逆序相加就能得到新的数。
代码:
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#define maxn 100
using namespace std;
int n,a[2][maxn];
char s[maxn];
bool huiwen(int x)
{
  int i,j,k;
  i=1,j=a[x][0];
  for(;i<j;i++,j--)
    if(a[x][i]!=a[x][j])return 0;
  return 1;  
}
void readdata()
{
  int i,j,k;
  scanf("%d%s",&n,s);
  k=strlen(s);
  for(i=k-1;i>=0;i--)
    {
      if(isdigit(s[i]))j=s[i]-'0';
      if(islower(s[i]))j=s[i]-'a'+10;
      if(isupper(s[i]))j=s[i]-'A'+10;
      a[0][++a[0][0]]=j;
    }
  if(huiwen(0)){printf("STEP=0\n");exit(0);}  
}
void add(int x)
{
  int i,j,k,last,y=1-x;
  a[x][0]=a[y][0];
  for(last=0,i=1;i<=a[y][0];i++)
    {
      j=a[y][0]+1-i;
      a[x][i]=a[y][i]+a[y][j]+last;
      last=a[x][i]/n,a[x][i]%=n;
    }
  if(last>0)a[x][++a[x][0]]=last;  
}
int main()
{
  readdata();
  for(int i=1;i<=30;i++)
    {
      add(i%2);
      if(huiwen(i%2)){printf("STEP=%d\n",i);return 0;}
    }
  printf("Impossible!\n"); 
  return 0;
}


来源:yuyanggo