【USACO 1.2.5】双重回文数
【题目描述】
如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做“回文数”。例如,12321就是一个回文数,而77778就不是。当然,回文数的首和尾都应是非零的,因此0220就不是回文数。
事实上,有一些数(如21),在十进制时不是回文数,但在其它进制(如二进制时为10101)时就是回文数。
编一个程序,从文件读入两个十进制数N (1 <= N <= 15)S (0 < S < 10000)然后找出前N个满足大于S且在两种或两种以上进制(二进制至十进制)上是回文数的十进制数,输出到文件上。
本问题的解决方案不需要使用大于32位的整型
【格式】
INPUT FORMAT:
(file dualpal.in)
只有一行,用空格隔开的两个数N和S。
OUTPUT FORMAT:
(file dualpal.out)
N行, 每行一个满足上述要求的数,并按从小到大的顺序输出.
【分析】
这道题教会了我写函数模板的重要性......
1 #include <cstdlib> 2 #include <iostream> 3 #include <cstdio> 4 #include <cmath> 5 #include <cstring> 6 const int maxl=100000; 7 using namespace std; 8 int shu_1[maxl],shu_2[maxl]; 9 int temp[maxl]; 10 //进制转换 11 void change(int *shu,int num,int system); 12 bool check(int *shu);//检查是否是回文数 13 int main() 14 { 15 int n,i,s,cnt=0; 16 17 //文件操作 18 freopen("dualpal.in","r",stdin); 19 freopen("dualpal.out","w",stdout); 20 scanf("%d%d",&n,&s); 21 22 for (i=s+1;;i++) 23 { 24 if (cnt==n) break; 25 int lj=0; 26 for (int j=2;j<=10;j++) 27 { 28 change(shu_1,i,j); 29 if (check(shu_1)) lj++; 30 } 31 if (lj>=2) {printf("%d\n",i);cnt++;} 32 } 33 return 0; 34 } 35 //把一个num转换成system进制的数 36 void change(int *shu,int num,int system) 37 { 38 int point=0; 39 memset(shu,0,sizeof(shu)); 40 memset(temp,0,sizeof(temp)); 41 point++; 42 //进制转换 43 while (num!=0) 44 { 45 int t; 46 t=num%system; 47 num=num/system; 48 temp[point++]=t; 49 } 50 point--; 51 for (int i=point;i>=1;i--) shu[point-i+1]=temp[i]; 52 shu[0]=point;//长度 53 return; 54 } 55 bool check(int *shu) 56 { 57 int point=shu[0],i; 58 for (i=1;i<=(point/2)+1;i++) 59 if (shu[i]!=shu[point-i+1]) return 0; 60 return 1; 61 }