P1015 [NOIP1999 普及组] 回文数
- 考点:
高精度加法、判回文
; - 视频讲解:
稍后上传; - 测评链接:P1015 [NOIP1999 普及组] 回文数;
题意&分析
给定 N N N 进制数 M M M, 1 ≤ N ≤ 16 1 \le N \le 16 1≤N≤16,进制最大的情况是十六进制,根据题目的要求最多不超过 30 30 30 次转换为回文数。
例如, N = 10 , M = 8787 N = 10, M = 8787 N=10,M=8787。
又如:对于十进制数 8787 8787 8787:
STEP1:
87
+
78
=
16587
+
78
=
165
87+78=16587+78=165
87+78=16587+78=165;
STEP2:
165
+
561
=
726165
+
561
=
726
165+561=726165+561=726
165+561=726165+561=726;
STEP3:
726
+
627
=
1353726
+
627
=
1353
726+627=1353726+627=1353
726+627=1353726+627=1353;
STEP4:
1353
+
3531
=
48841353
+
3531
=
4884
1353+3531=48841353+3531=4884
1353+3531=48841353+3531=4884;
两个主要的功能(判断回文、高精度加法运算):
- 100 位数,明显要高精度解决,而且是要高精度加法。
- 判断回文,双指针头尾判断是否不相等。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 5005;
int n, m, len;
string s;
int a[N], b[N];
// 判断回文
bool is_re() {
int l = 1, r = len;
while ( l <= r ) { // 左指针右移、右指针左移
if ( a[l++] != a[r--] ) return false;
}
return true;
}
// 高精度加法
void add( int a[], int b[]) { // 加数 a = a + b;
int x = 0;
for (int i = 1; i <= len; i++) {
a[i] = a[i] + b[len - i + 1] + x;
x = a[i] / n;
a[i] %= n;
}
// 最高位进位处理
while ( x > 0 ) {
a[++len] = x % n;
x /= n;
}
}
void print() {
for (int i = len; i >= 1; i--)
cout << a[i];
cout << endl;
}
int main() {
cin >> n;
cin >> s;
len = s.size();
for (int i = len - 1, j = 1; i >= 0; i--) {
if ( s[i] >= 'A' )
a[j++] = (s[i] - 'A') + 10;
else
a[j++] = (s[i] - '0');
}
int cnt = 0; // 记录转换次数
while ( cnt < 30 && !is_re() ) { // 不超过30次,不为回文数
for (int i = 1; i <= len; i++) // copy 一遍 a 数组到 b 中
b[i] = a[i];
add(a, b); // a = a + b;
// print();
cnt++;
}
if ( cnt >= 30 ) cout << "Impossible!" << endl;
else cout << "STEP=" << cnt << endl;
return 0;
}