题目:P1015 [NOIP 1999 普及组] 回文数

题目描述

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

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

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

STEP1: 87 + 78 = 165 87+78=165 87+78=165
STEP2: 165 + 561 = 726 165+561=726 165+561=726
STEP3: 726 + 627 = 1353 726+627=1353 726+627=1353
STEP4: 1353 + 3531 = 4884 1353+3531=4884 1353+3531=4884

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

写一个程序,给定一个 N N N 2 ≤ N ≤ 10 2 \le N \le 10 2N10 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,其中 ans \text{ans} ans 为最少得到回文数的步数。

否则输出 Impossible!

输入输出样例 #1

输入 #1

10
87

输出 #1

STEP=4

代码

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int N;
string M;

vector<int> add(vector<int> &a, vector<int> &b){
    vector<int> res;
    int t = 0;
    for(int i = 0; i < a.size(); i ++){
        t += a[i] + b[i];
        res.push_back(t % N);
        t /= N;
    }
    if(t){
        res.push_back(t);
    }
    return res;
}

int main(){
    cin >> N;
    cin >> M;
    vector<int> m;
    for(int i = 0; i < M.size(); i ++){
        if(M[i] >= '0' && M[i] <= '9'){
            m.push_back(M[i] - '0');
        }
        else{
            m.push_back(M[i] - 'A' + 10);
        }
    }

    for(int step = 0; step <= 30; step ++){
        auto mY = m; // mY为本身, m为翻转后的数
        reverse(m.begin(), m.end());
        if(mY == m){
            cout << "STEP=" << step;
            return 0;
        }
        m = add(mY, m);
    }
    puts("Impossible!");
    return 0;
}

结果

在这里插入图片描述
在这里插入图片描述

Logo

集算法之大成!助力oier实现梦想!

更多推荐