Dual Palindromes
Description
一个数字如果从左往右读和从右往左读都是一样的那么它就是回文数。数字12321显然就是回文数,而77778就不是。当然,回文数不可能前端和末尾同时有0,所以说0220不是回文数。
十进制数21用十进制表示不是回文数,但是21实际上用二进制表示却是回文数(10101).
编写一个程序读取两个十进制数字:
• N (1 <= N <= 15)
• S (0 < S < 10000)
然后找到并输出严格大于S的前N个十进制数字,这N个数字满足在两种或两种以上进制(二进制至十进制)上是回文数。
此问题的解决方案不需要操作大于标准32位的整数。
PROGRAM NAME: dualpal
INPUT FORMAT
单行用空格分隔整数N和S
SAMPLE INPUT (file dualpal.in)
3 25
OUTPUT FORMAT
一共N行,每行为一个十进制数字,该数字满足在两种或两种以上进制(二进制至十进制)上是回文数。这些数字需要按照从小到大的顺序排列。
SAMPLE OUTPUT (file dualpal.out)
26
27
28
设计算法
这个题起初写出来没过,感觉其实是没错的,去了洛谷看了一下它的翻译结果是自己翻译理解错了,我以为条件是这N个数字满足在以进制base(2 <= base <= 10)表示时是回文数就行了,结果其实是要在两种及以上进制表示都是回文数才算符合条件。
这题其实不难,甚至代码中的函数都可以从Palindromic Squares这道题中照搬,一些思路在Palindromic Squares中也讲了,那么就只需要用几个动态变量来记录一下值用于设置终止条件和输出条件就行了。
C++编写
/*
ID:your_id_here
TASK: dualpal
LANG: C++
*/
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const string t="0123456789";
int N,S;
bool check(string str)
{
int len=str.size();
for(int i=0;i<len/2;i++)
{
if(str[i]!=str[len-1-i])
return false;
}
return true;
}
string conv(int x,int y)
{
string num;
while(y)
{
int a = y%x;
y/=x;
num+=t[a];
}
reverse(num.begin(),num.end());
return num;
}
void solve()
{
int rec1=0;
for(int i=S+1;rec1<N;i++)
{
int rec2=0;
for(int j=2;j<11;j++)
{
if(check(conv(j,i)))
++rec2;
if(rec2==2)
{
cout<<i<<endl;
++rec1;
break;
}
}
}
}
int main()
{
freopen("dualpal.in","r",stdin);
freopen("dualpal.out","w",stdout);
cin>>N>>S;
solve();
return 0;
}