ZJU1078-Palindrom Numbers(解题来自《ACM国际大学生程序设计竞赛题解(1)》
【题目大意】
问题描述:
如果一个数从左边读和从右边读一样,那么我们说这是一个回文数。例如,75457是一个回文数。
当然,数的这个特性还依赖于表示它的进制。如果用十进制表示17,它不是回文数;但是如果是用二进制(10001)表示它,它就是一个回文数。
本题的目标是,在二~十六进制下,确定给出的一系列数是否是回文数。
【输入格式】:
输入包含一些整数。每个数n(0<n<50000)用十进制表示,每个数一行。输入0结束。
【输出格式】:
程序输出信息:"Number i is palindrom in basis".i是给定的数,接着使出进制,在该进制下数i是回文。如果这个数在二~十六进制下都不是回文数,程序就输出信息:“Number i is not a palindrom”。
【算法分析】
本题是关于回文数的问题。主要是解决一个数在某进制下的分解,以及回文的判断。
(1)在某进制下的分解
设数组c存放数值n在某进制i(i=2~16)下的分解:
char c[30];
结合使用模运算和整除运算就可以分解。
分解以后的数字位数保存在变量len中。
(2)回文数的判断
将数组c按长度len对折,看看对应的位是否相同。只要有一个不同,就不是回文数,如果是回文,将此时的进制i保存到数组base中(base[i]=1);
int base[17]={0};
如果数组base中一个进制都没有保存下来,则说明数值n一个回文数也没有;否则,输出数组base对应的下标。
【程序代码】
#include <iostream> #include <cstdio> using namespace std; int main() { int n; int i,j; while(scanf("%d",&n)&&n!=0) { int sign=0; char c[30]; int base[17]={0}; for(i=2;i<=16;i++) { int m=n; int len=0; while(m) { c[len++]=m%i; m=m/i; } sign=1; for(j=0;j<len/2&&sign;j++) if(c[j]!=c[len-j-1]) sign=0; if(sign) base[i]=1; } sign=1; for(i=2;i<=16;i++) if(base[i]==1) sign=0; if(sign) printf("Number %d is not a palindrom\n",n); else { printf("Number %d is palindrom in basis",n); for(i=2;i<=16;i++) if(base[i])printf(" %d",i); printf("\n"); } } return 0; }