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!";
}
posted @ 2020-08-15 23:26  lemu  阅读(147)  评论(0编辑  收藏  举报
4