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

 

你可能感兴趣的:(USACO)