70 回文数

作者: Turbo时间限制: 1S章节: 模拟

问题描述 :

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

  我们现在需要产生回文数,步骤如下:

给定一个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(其中16进制数字为0-9与A-F),求最少经过几步可以得到回文数。
  如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”

输入说明 :

两行,N与M

输出说明 :

如果能在30步以内得到回文数,输出“STEP=xx”(不含引号),其中xx是步数;否则输出一行”Impossible!”(不含引号)

输入范例 :

9
87

输出范例 :

STEP=6

算法思想:

基本暴力求解,(没想到直接敲下来没有调试就ac了…)首先判断m是不是回文,不是的话进行相应的操作继续监测,这里对m进行操作的时候,用到了大数操作的思想,处理进位之类的,
详细请见注释。

代码:

#include
#include
#include
#include
char word[18]="0123456789ABCDEFG";
int reword(char m[])//判断m是否是回文
{
	int len=strlen(m);
	int i,j;
	for(i=0,j=len-1;j>i;i++,j--)
	{
		if(m[i]!=m[j])
		{
			return 0;
		}
	}
	return 1;
}
int main()
{
	int n,i,j,flag=0;//n是进制,flag有0,1两种状态,flag为1,m是回文,0不是回文
	char m[100];
	scanf("%d",&n);
	getchar();//吸收回车
	gets(m);
	for(i=0;i<=30;i++)//循环检测当前的m是否是回文
	{
	//	puts(m);
		if(reword(m))//如果是回文 的话直接跳出循环
		{
			flag=1;
			break;
		}
		int temp[100],sum[100],k=0;//这里temp是同来存放m转化为int型,并且把A,B,C装换成数字
		for(j=0;m[j]!='\0';j++)
		{
			if(m[j]>='0'&&m[j]<='9')
				temp[k++]=m[j]-'0';
			else if(m[j]>='A'&&m[j]<='G')
				temp[k++]=(int)(m[j]-55);
		}
		for(j=0;j<k;j++)//这里就是相当于原来的数,加倒过来的数,就是首尾相加,存在sum中,但是注意,这里在进位过程中,最高位可能会有进位,所以要在是s[0]这里先空出来,
		{
			sum[j+1]=temp[j]+temp[k-j-1];
		}
		int jin=0;
		int len=j+1;//因为空了一个是s[0],所以这里sum的长度会比temp长度大1.
		for(;j>=1;j--)//这一步就是进位处理,这里sum的存在,就是为了相加之后取余,方便对m进行变换
		{
			jin=jin+sum[j];
			sum[j]=jin%n;
			jin=jin/n;
		}
		sum[0]=jin;
		if(sum[0]==0)//如果s[0]上没有进位,从1开始
		{
			for(k=1;k<len;k++)
			{
				m[k-1]=word[sum[k]];
			}
			m[k-1]='\0';
		}
		else//否则从0开始
		{
			for(k=0;k<len;k++)
			{
				m[k]=word[sum[k]];
			}
			m[k]='\0';
		}
	}
	if(flag==1)
		printf("STEP=%d\n",i);
	else
		printf("Impossible!\n");
    return 0;
}	

你可能感兴趣的:(东华复试)