回文数 \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 N(2≤N≤10 或 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;
}