vijos p1304 回文数 简洁写法
描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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(2<=N<=10或N=16)
第二行为N进制数M(0<=M<=maxlongint)
输出格式
共一行
第一行为“STEP=”加上经过的步数或“Impossible!”
样例1
样例输入1
9
87
样例输出1
STEP=6
限制
各个测试点1s
来源
NOIP1999提高组第2题
思路
用string存储,每一位当做int来用,比起我看的题解里用数组的简洁很多。
#include <bits/stdc++.h>
#define fu(a, b, c) for (int a = b; a <= c; a++)
#define fd(a, b, c) for (int a = b; a >= c; a--)
using namespace std;
int n;
string s;
int main() {
cin >> n >> s;
for (auto &c : s) //要修改值所以用引用
c = c >= 65 ? c - 55 : c - 48;
fu(i, 0, 30) {
string s1 = s;
reverse(s1.begin(), s1.end());
if (s1 == s) {
cout << "STEP=" << i;
return 0;
}
int sz = s.size() - 1;
fd(i, sz, 1) {
s[i] += s1[i];
s[i - 1] += s[i] / n, s[i] %= n;
}
s[0] += s1[0];
if (s[0] >= n)
s.insert(0, 1, char(s[0] / n)), s[1] %= n;
}
cout << "Impossible!";
}