xtu p1143 回文数

久未见 提交于 2020-03-02 15:11:30

描述

若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。例如:给定一个 10进制数 56,将 56加 65(即把56从右向左读),得到 121是一个回文数。又如,对于10进制数87:

STEP187+78 = 165
STEP2165+561 = 726
STEP3726+627 = 1353
STEP41353+3531 = 4884

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

写一个程序,给定一个N(3≤N≤10或N=16)进制数 M.求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出**“Impossible”** 。
格式
输入格式

给定一个N(3≤N≤10或N=16)进制数 M
输出格式
最少几步。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible”。
样例
输入样例

9 87

输出样例

6

限制
时间限制: 1000 ms
内存限制: 65536 KB

struct bign{
	int d[1000];
	int len;
	bign(){
		memset(d,0,sizeof(d));
		len=0;
	}
};

bign change(char str[1000]){
	bign a;
	a.len=strlen(str);
	for(int i=0;i<a.len;i++){
		a.d[i]=str[a.len-i-1]-'0';
	}
	return a;
}

bign add(bign a,bign b,int p){
	bign c;
	int carry=0;
	for(int i=0;i<a.len||i<b.len;i++){
		int temp=a.d[i]+b.d[i]+carry;
		c.d[c.len++]=temp%p;
		carry=temp/p;		
	}
	if(carry!=0){
		c.d[c.len++]=carry;
	}
	return c;
}

bign reverseb(bign a){
	for(int i=0;i<a.len/2;i++){
		int temp=a.d[i];
		a.d[i]=a.d[a.len-i-1];
		a.d[a.len-i-1]=temp;
	}
	return a;
}

bool hw(bign a){
	bool flag=true;
	for(int i=0;i<a.len/2;i++){
		if(a.d[i]!=a.d[a.len-i-1]){
			flag=false;
			break;
		}
	}
	return flag;
}

void print(bign a){
	for(int i=a.len-1;i>=0;i--){
		printf("%d",a.d[i]);
	}
	printf("\n");
}

int main(){
	char st1[1000];
	int p;
	scanf("%d %s",&p,st1);
	bign a=change(st1);
	int i,cnt=0;
	for(i=0;i<30;i++){
		bign b=reverseb(a);
		a=add(a,b,p);
		cnt++;
		if(hw(a)) break;
	} 
	if(i==30) printf("Impossible");
	else printf("%d",cnt);
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!