首页 > 代码库 > 【USACO 1.2.5】双重回文数

【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 }