iDual Palindromes(枚举)

 

 

Dual Palindromes
Mario Cruz (Colombia) & Hugo Rickeboer (Argentina)

A number that reads the same from right to left as when read from left to right is called a palindrome. The number 12321 is a palindrome; the number 77778 is not. Of course, palindromes have neither leading nor trailing zeroes, so 0220 is not a palindrome.

The number 21 (base 10) is not palindrome in base 10, but the number 21 (base 10) is, in fact, a palindrome in base 2 (10101).

Write a program that reads two numbers (expressed in base 10):

  • N (1 <= N <= 15)
  • S (0 < S < 10000)

and then finds and prints (in base 10) the first N numbers strictly greater than S that are palindromic when written in two or more number bases (2 <= base <= 10).

Solutions to this problem do not require manipulating integers larger than the standard 32 bits.

PROGRAM NAME: dualpal

INPUT FORMAT

A single line with space separated integers N and S.

SAMPLE INPUT (file dualpal.in)

3 25

OUTPUT FORMAT

N lines, each with a base 10 number that is palindromic when expressed in at least two of the bases 2..10. The numbers should be listed in order from smallest to largest.

SAMPLE OUTPUT (file dualpal.out)

26
27
28

 

   题意:

   在S数的基础上找出最先的N个十进制的数(十进制输出),这些数至少有两种或者两种以上进制(范围是二进制到十进制)为回文串。

 

   思路:

   这题与上一题类似,只是循环的东西不一样。同样的用把转换进制的功能封装在一个函数中,另外把判断是否为回文串的功能封装在另一个函数中。通过循环进制(2到10)来积累一个数有多少个进制为回文串,如果找到两个则跳出循环。用sum来表示已经找到两种或两种以上进制数的数量,当sum积累到N时,跳出总的循环(总的循环包括S不断自增1)。

 

   Wrong and test:

 

#include<stdio.h>
#include<string.h>
//#include<stdlib.h>
int change[20];
int S,length,number;
//转换进制函数
int c(int i)
{
	memset(change,0,sizeof(change));
	int j=0;
	while(number)
	{
	   change[j++]=number%i;
	   number/=i;
	}
//备注释的时候不小心把下面这句也注释掉了
//最后导致输出的结果很不一样	
        length=j;
//每一步输出查看,看是否有正确存储到change中
//	for(i=length-1;i>=0;i--)  
//	 printf("%d",change[i]);
//	 printf("\n");
//	system("pause");
}
//测试是否为回文串的函数
int test()
{
	int i,j;
	for(i=0,j=length-1;i<length;i++,j--)
	 if(change[i]!=change[j]) return 0;
	return 1;
}

int main()
{
	int N,i,time=0,temp;
	scanf("%d%d",&N,&S);
	while(1)
	{
	 S++;
	 temp=0;
	 for(i=2;i<=10;i++)
	  { 
		number=S;  
                c[i];
//刚开始错在上面这两句话写的顺序反了
//如果调反的话,则number为被赋值就开始将number转换进制
//那实际change[20]为'\0'(通过上面测试发现这里有错误)
		if(test())   temp++;
//一开始读错题了,是要两个或者两个以上才输出
		if(temp>=2)
		{
			printf("%d\n",S);
			time++;
			break;
		}
	  }
	  if(time==N)  break; 
      //time累计到N则跳出总循环
    }
	return 0;
}

   AC:

/*
TASK:dualpal
LANG:C
ID:sum-g1
*/
#include<stdio.h>
#include<string.h>
int change[20];
int S,length,number;
int c(int i)
{
	int j=0;
	while(number)
	{
	   change[j++]=number%i;
	   number/=i;
	}
	length=j;
}
int test()
{
	int i,j;
	for(i=0,j=length-1;i<length;i++,j--)
	 if(change[i]!=change[j]) return 0;
	return 1;
}
int main()
{
FILE *fin =fopen("dualpal.in","r");
 FILE *fout=fopen("dualpal.out","w");	
int N,i,time=0,temp;
	fscanf(fin,"%d%d",&N,&S);
	while(1)
	{
	 S++;
         temp=0;
	 for(i=2;i<=10;i++)
	  { 
		number=S;  
//必须赋值给number才对数进行取余和用除法处理尾数
//如果直接在S上进行这些操作,则改变了S本身,而最后又要输出S
//所以如果不赋值给number的话最后输出的数会全都是0
		c(i);
		if(test())  temp++;
//看temp积累到两个没有
 		if(temp==2)
 		 {fprintf(fout,"%d\n",S);time++;break;}
//time是用来积累已经找到几个满足条件的数
	  }
	  if(time==N)  break;
    }
	return 0;
}

   总结:

   技巧的东西,从上一题就学到了。但是还是出现了很多粗心的地方,不过现在也不会找那么久的错误了,可能犯的次数多了,大概也能知道自己会错在哪里。有时候写完代码而且AC了这道题后,看下别人写的代码,也是一种学习的过程,或许能学到更多技巧的地方。

你可能感兴趣的:(dual)