NOIP 1999普及组 回文数

Description

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。例如121就是一个回文数。 
对于任意一个数,可以进行如下变换,可以得到一个回文数。 

例如: 
给定一个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,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!” 

Input

第一行为N 
第二行为M

Output

STEP=步数 
或 
Impossible!

Sample Input

9
87

Sample Output

STEP=6

本题的解题思路大致是,先输入,随后进行存储(用十进制的方式),然后相加(注意进制问题last=a/n;a=a%n;)最后再判断是否回文即可,依次循环30次

代码如下:

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>

int n,a[2][100];
char s[100];

bool huiwen (int x)//如果一直相等,就返回1,一旦不相等就返回0
{
	int i,j=a[x][0];
	for(i=1;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;        //a[0][0]用来存储数字的位数,其后存储字符在十进制中的意思
	}
	if(huiwen(0))
	{
		printf("STEP=0\n");
		exit(0);
	}
}

void add(int x)                             //x为1,0,1,0,1。。
{						//y为0,1,0,1,0。。
	int i,j,last,y=1-x;
	a[x][0]=a[y][0];			//a[y][0],表示数字的长度
	last=0;	
	for(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);                     //i为基数,add(1);huiwen(1);
      if(huiwen(i%2))		    //i为偶数,add(0);huiwen(0);
	  {
		  printf("STEP=%d\n",i);
		  return 0;
	  }
    }
  printf("Impossible!\n"); 
  return 0;
}

猜你喜欢

转载自blog.csdn.net/zmc1248234377/article/details/79516442
今日推荐