洛谷 P1015 [NOIP1999 普及组] 回文数

[NOIP1999 普及组] 回文数

题目描述

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

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

又如:对于十进制数 \(87\)

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

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

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

输入格式

两行,分别是 \(N\)\(M\)

输出格式

如果能在 \(30\) 步以内得到回文数,输出格式形如 STEP=ans,其中 \(\text{ans}\) 为最少得到回文数的步数。

否则输出 Impossible!

样例 #1

样例输入 #1

10
87

样例输出 #1

STEP=4

分析

这里考察高精度加法
原理根我们平时手写的竖式
分享一下我的高精度加法的模板(我习惯用vector储存大整数)

vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);
    vector<int> C;
    int t = 0;//存进位
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);//①
        t /= 10;//②
    }
    if (t) C.push_back(t);//处理最后进位
    return C;//结果
}

以上是针对 \(10\) 进制大整数加法的模板,
在这题中要求是 \(N\) 进制,
那么可以将模板中的①和②处的10改为 \(N\) 即可。

C.push_back(t%N);t/=N;
在这题中还需要判断是否为回文数,
可以使用双指针 \(i\) 从头, \(j\) 从末尾各自向中间移动,
只要出现 a[i]!=a[j] 则说明不是回文数。
那么就可以按题目要求进行 \(30\) 次操作,若没找到回文数则输出 \(Impossible!\)
接下来是代码:

AC CODE (cpp)

#include<bits/stdc++.h> //noip 1999 回文数
using namespace std;
bool check(vector<int> a){
	for(int i = 0,j = a.size()-1;i<j;i++,j--)if(a[i]!=a[j])return false;
	return true;
}
vector<int> f(vector<int> a){
	for(int i = 0,j = a.size()-1;i<j;i++,j--)swap(a[i],a[j]);
	return a;
}

int main(){
	int N;
	cin>>N;
	string s;
	cin>>s;
	vector<int> A;
	for(int i = s.size()-1;~i;--i){
		if(isdigit(s[i]))A.push_back(s[i]-'0');
		else A.push_back(s[i]-'A'+10);
	}
	if(check(A))return puts("0"),0;
	for(int T = 1;T<=30;T++){
		vector<int> B = f(A);
		int t = 0;
		vector<int> C;
		for(int i = 0;i<A.size();i++){
			t += A[i]+B[i];
			C.push_back(t%N);
			t/=N;
		}
		if(t)C.push_back(t);
		if(check(C))return printf("STEP=%d",T),0;
		A.clear();
		A = C; 
	}
	return puts("Impossible!"),0;
} 

如有错误请指出。

posted @ 2022-08-14 20:44  Andy2035  阅读(194)  评论(0)    收藏  举报