题目:ACwing 1346. 回文平方
题目来源:https://www.acwing.com/problem/content/1348/
描述:
回文数是指数字从前往后读和从后往前读都相同的数字。
例如数字 12321 就是典型的回文数字。
现在给定你一个整数 B,请你判断 1∼300 之间的所有整数中,有哪些整数的平方转化为 B 进制后,其 B 进制表示是回文数字。
输入格式
一个整数 B。
输出格式
每行包含两个在 B 进制下表示的数字。
第一个表示满足平方值转化为 B 进制后是回文数字那个数,第二个数表示第一个数的平方。
所有满足条件的数字按从小到大顺序依次输出。
数据范围
$2≤B≤20,$
对于大于 9 的数字,用 A 表示 10,用 B 表示 11,以此类推。
输入样例:
输出样例:
1 2 3 4 5 6 7 8 9 10 11 12
| 1 1 2 4 3 9 11 121 22 484 26 676 101 10201 111 12321 121 14641 202 40804 212 44944 264 69696
|
算法1:$O(n)$
回文:
利用双指针,一个指针在前,一个指针在后,然后如果向两边靠拢,如果不等返回flase
1 2 3 4 5 6 7
| bool check(string s) { for(int i = 0, j = s.size() - 1; i < j; i++, j--) if (s[i] != s[j]) return false; return true; }
|
短除法:
n / b等到余数,当 n / b = 0 的时候停止,最后余数的余数倒着写。
如:
123 / 7 = 17 … 4
17 / 7 = 2 … 3
2 / 7 = 0 … 2
所以 123的 7 进制为234 = $2 * 7^2 + 3 * 7^1 + 4 * 7^0 = 49 * 2 + 21 + 4 = 123$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> #include <algorithm>
using namespace std; int b;
bool check(string s) { for(int i = 0, j = s.size() - 1; i < j; i++, j--) if (s[i] != s[j]) return false; return true; }
char get(int n) { if (n <= 9) return n + '0'; return 'A' + n - 10; }
string base(int n, int b) { string res; while(n) res += get(n % b), n /= b; reverse(res.begin(), res.end()); return res; }
int main() { cin >> b;
for(int i = 1; i <= 300; i++) { string s = base(i * i, b); if (check(s)) { cout << base(i, b) << ' ' << s << endl; } } return 0; }
|