回文数

回文数 ⁡ \operatorname{回文数}

题目链接: luogu P1015 ⁡ \operatorname{luogu\ P1015} luogu P1015

题目

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

例如:给定一个十进制数 56 56 56 ,将 56 56 56 65 65 65(即把 56 56 56 从右向左读),得到 121 121 121 是一个回文数。

又如:对于十进制数 87 87 87

STEP 1 1 1 87 + 78 = 165 87+78=165 87+78=165
STEP 2 2 2 165 + 561 = 726 165+561=726 165+561=726
STEP 3 3 3 726 + 627 = 1353 726+627=1353 726+627=1353
STEP 4 4 4 1353 + 3531 = 4884 1353+3531=4884 1353+3531=4884

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

写一个程序,给定一个 N ( 2 ≤ N ≤ 10 N(2 \le N \le 10 N2N10 N = 16 ) N=16) N=16 进制数 M M M 100 100 100 位之内),求最少经过几步可以得到回文数。如果在 30 30 30 步以内(包含 30 30 30 步)不可能得到回文数,则输出 Impossible!

输入

两行,分别是 N N N M M M

输出

如果能在 30 30 30 步以内得到回文数,输出格式形如 STEP=ans ,其中 a n s ans ans 为最少得到回文数的步数。

否则输出 Impossible!

样例输入

10
87

样例输出

STEP=4

思路

这道题是一道字符串模拟。

就高精度模拟,记得是 n n n 进制的就可以了。

代码

#include<cstdio>
#include<cstring> 

using namespace std;

int n, a[1000001], ans, l, time, b[1000001];
char c[101];
bool yes;

int main() {
	scanf("%d", &n);//读入
	getchar();
	scanf("%s", &c);
	l = strlen(c);//求出数的长度
	for (int i = 0; i < l; i++) {
		if (c[i] >= 'A' && c[i] <= 'F') a[l - i - 1] = c[i] - 'A' + 10;
			else a[l - i - 1] = c[i] - 48;//转成数字
	}
	
	while (!yes) {
		if (time > 30) break;//超过了三十次
		bool hui = 1;
		for (int i = 0; i < l; i++) {
			if (a[i] != a[l - i - 1]) {
				hui = 0;//不是回文数
			}
			b[l - i - 1] = a[i];//求出反过来的数
		}
		if (hui) {
			printf("STEP=%d", time);//是回文数,输出
			return 0;
		}
		
		for (int i = 0; i < l; i++) {//高精加
			a[i] = a[i] + b[i];
		}
		for (int i = 0; i <= l; i++) {
			a[i + 1] += a[i] / n;//除和取模的时候是/n,因为是n进制
			a[i] %= n;
		}
		if (a[l]) l++;//位数增加
		
		time++;//做了一步
	}
	
	printf("Impossible!");//三十步找不到
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值