关于最小回文数

qinguan0619 2009-08-28 09:30:08
给定一个数(该数可能很大),求大于该数的最小回文数,请问有什么好一点的方法?有时间限制,算法需要尽量快一点。
...全文
549 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
绿色夹克衫 2009-08-29
  • 打赏
  • 举报
回复
同样的算法,Python慢个5-6倍是有可能的,但应该也不至于会超时,不行的话就别用字符串来做了,直接用数字试试,提前定义一个10^m的数组{1,10,100,1000,10000....}用二分来取Log,这样应该能够快一些。
linren 2009-08-28
  • 打赏
  • 举报
回复
上面的程序还是有问题……
下面的应该是正确的了:

【程序】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void fun(int n){
int i,j,k,x,y,len;
char a[20],b[35];
printf("%d-->",n);
if(n<=0){
printf("0\n");return;
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
sprintf(a,"%d",n);
len=strlen(a);
if(len==1){
if(n<9) printf("%d\n",n+1);
else printf("11\n");
}else if(len%2==1){
for(i=0;i<(len/2+1);i++) b[i]=a[i];
k=atoi(b);
for(i=len/2-1,j=len/2+1;i>=0;i--,j++){
if(a[i]!=a[j]) break;
}
if(j==len||a[i]<a[j]){
k++;
printf("%d",k);
sprintf(b,"%d",k);
for(i=len/2-1;i>=0;i--) printf("%c",b[i]);
printf("\n");return;
}
if(a[i]>a[j]){
printf("%d",k);
for(i=len/2-1;i>=0;i--) printf("%c",a[i]);
printf("\n");return;
}
}else{
i=len/2-1;
j=i+1;
for(k=0;k<=i;k++) b[k]=a[k];
if(a[i]>a[j]){
printf("%s",b);
for(k=i;k>=0;k--) printf("%c",b[k]);
printf("\n");return;
}
if(a[i]==a[j]){
for(x=i-1,y=j+1;x>=0;x--,y++){
if(a[x]!=a[y]) break;
}
if(y==len||a[x]<a[y]){
k=atoi(b);
k++;
sprintf(b,"%d",k);
printf("%d",k);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
if(a[x]>a[y]){
printf("%s",b);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
}
if(a[i]<a[j]){
k=atoi(b);
k++;
sprintf(b,"%d",k);
printf("%d",k);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
}
}

int main(){
fun(121);
return 0;
}

【运行结果】
121-->131
Press any key to continue

【说明】
本身是回文数时并不是直接打印这个数……
而应该是找下一个回文数……
5楼把这个给弄错了……
linren 2009-08-28
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void fun(int n){
int i,j,k,x,y,len;
char a[20],b[35];
printf("%d-->",n);
if(n<=0){
printf("0\n");return;
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
sprintf(a,"%d",n);
len=strlen(a);
if(len==1){
if(n<9) printf("%d\n",n+1);
else printf("11\n");
}else if(len%2==1){
for(i=0;i<(len/2+1);i++) b[i]=a[i];
k=atoi(b);
for(i=len/2-1,j=len/2+1;i>=0;i--,j++){
if(a[i]!=a[j]) break;
}
if(j==len){
printf("%d\n",n);return;
}
if(a[i]>a[j]){
printf("%d",k);
for(i=len/2-1;i>=0;i--) printf("%c",a[i]);
printf("\n");return;
}
if(a[i]<a[j]){
k++;
printf("%d",k);
sprintf(b,"%d",k);
for(i=len/2-1;i>=0;i--) printf("%c",b[i]);
printf("\n");return;
}
}else{
i=len/2-1;
j=i+1;
for(k=0;k<=i;k++) b[k]=a[k];
if(a[i]>a[j]){
printf("%s",b);
for(k=i;k>=0;k--) printf("%c",b[k]);
printf("\n");return;
}
if(a[i]==a[j]){
for(x=i-1,y=j+1;x>=0;x--,y++){
if(a[x]!=a[y]) break;
}
if(y==len){
printf("%d\n",n);return;
}
if(a[x]>a[y]){
printf("%s",b);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
if(a[x]<a[y]){
k=atoi(b);
k++;
sprintf(b,"%d",k);
printf("%d",k);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
}
if(a[i]<a[j]){
k=atoi(b);
k++;
sprintf(b,"%d",k);
printf("%d",k);
for(x=i;x>=0;x--) printf("%c",b[x]);
printf("\n");return;
}
}
}

int main(){
fun(1);
fun(9);
fun(21);
fun(12);
fun(231);
fun(123);
fun(1222);
fun(2111);
return 0;
}

【运行结果】
1-->2
9-->11
21-->22
12-->22
231-->232
123-->131
1222-->1331
2111-->2112
Press any key to continue
linren 2009-08-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xiaoyu821120 的回复:]
其实这个问题很简单,利用回文数的特性来求解,把所有的情况都理清楚,关键在于判断靠近中间两位数的大小来制定策略。
举几个例子就知道了
1->2
9->11
21->22
12->22
231->232
123->131
1222->1331
2111->2112
[/Quote]
原来如此……
我又理解错了……
xiaoyu821120 2009-08-28
  • 打赏
  • 举报
回复
其实这个问题很简单,利用回文数的特性来求解,把所有的情况都理清楚,关键在于判断靠近中间两位数的大小来制定策略。
举几个例子就知道了
1->2
9->11
21->22
12->22
231->232
123->131
1222->1331
2111->2112
linren 2009-08-28
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <string.h>

void fun(int n){
int i,j,k,len;
char a[35],b[35];

memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
sprintf(a,"%d",n);
len=strlen(a);
for(i=len-1,j=0;i>=0;i--,j++) b[i]=a[j];
for(i=0;i<len-1;i++){
if(a[i]!=a[len-1]) continue;
for(j=len-2,k=i+1;k<j;j--,k++){
if(a[k]!=a[j]) break;
}
if(k<j) continue;
for(k=i-1,j=len;k>=0;k--,j++){
a[j]=a[k];
}
break;
}
if(i==len-1){
for(i=len-2,j=len;i>=0;i--,j++) a[j]=a[i];
}
for(i=0;i<len-1;i++){
if(b[i]!=b[len-1]) continue;
for(j=len-2,k=i+1;k<j;j--,k++){
if(b[k]!=b[j]) break;
}
if(k<j) continue;
for(k=i-1,j=len;k>=0;k--,j++){
b[j]=b[k];
}
break;
}
if(i==len-1){
for(i=len-2,j=len;i>=0;i--,j++) b[j]=b[i];
}
i=strlen(a);
j=strlen(b);
if(i>j) printf("%d-->%s\n",n,b);
else if(j>i) printf("%d-->%s\n",n,a);
else{
for(k=0;k<i;k++){
if(a[k]!=b[k]) break;
}
if(k==i){
printf("%d-->%s\n",n,a);return;
}
if(a[k]>b[k]) printf("%d-->%s\n",n,b);
else printf("%d-->%s\n",n,a);
}
}

int main(){
fun(12333);
fun(321);
fun(12332);
fun(2147483647);
return 0;
}

【运行结果】
12333-->1233321
321-->12321
12332-->123321
2147483647-->2147483647463847412
Press any key to continue

【说明】
有符号整型数最大为2147483647……
linren 2009-08-28
  • 打赏
  • 举报
回复
【程序】
#include <stdio.h>
#include <string.h>

void fun(int n){
int i,j,k,len;
char a[20],b[20];

memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
sprintf(a,"%d",n);
len=strlen(a);
for(i=len-1,j=0;i>=0;i--,j++) b[i]=a[j];
for(i=0;i<len-1;i++){
if(a[i]!=a[len-1]) continue;
for(j=len-2,k=i+1;k<j;j--,k++){
if(a[k]!=a[j]) break;
}
if(k<j) continue;
for(k=i-1,j=len;k>=0;k--,j++){
a[j]=a[k];
}
break;
}
if(i==len-1){
for(i=len-2,j=len;i>=0;i--,j++) a[j]=a[i];
}
for(i=0;i<len-1;i++){
if(b[i]!=b[len-1]) continue;
for(j=len-2,k=i+1;k<j;j--,k++){
if(b[k]!=b[j]) break;
}
if(k<j) continue;
for(k=i-1,j=len;k>=0;k--,j++){
b[j]=b[k];
}
break;
}
if(i==len-1){
for(i=len-2,j=len;i>=0;i--,j++) b[j]=b[i];
}
i=strlen(a);
j=strlen(b);
if(i>j) printf("%d-->%s\n",n,b);
else if(j>i) printf("%d-->%s\n",n,a);
else{
for(k=0;k<i;k++){
if(a[k]!=b[k]) break;
}
if(k==i){
printf("%d-->%s\n",n,a);return;
}
if(a[k]>b[k]) printf("%d-->%s\n",n,b);
else printf("%d-->%s\n",n,a);
}
}

int main(){
fun(12333);
fun(321);
fun(12332);
return 0;
}

【运行结果】
12333-->1233321
321-->12321
12332-->123321
Press any key to continue
qinguan0619 2009-08-28
  • 打赏
  • 举报
回复
我改了一下最后处理数据的顺序。。。

count=int(raw_input())
t=[]
for i in xrange(count):
t.append(raw_input())
print apply(palindrome,t)

报了个错:non-zero exit code
巨崩溃。。。
qinguan0619 2009-08-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 litaoye 的回复:]
判断一下该数长度的奇偶,然后截出前半截,生成回文数同该数比较大小,如果大于,则输出生成的回文数,
如果小于,则该数+1生成回文数,重复上面的判断就行,应该只有9999....9的情况需要特殊判断一下。
[/Quote]
其实我用的就是这种方法,超时,不过我是用python写的。。。难道语言的差异有那么大??。。。

#palindrome函数返回最小回文数
def palindrome(num):
length=len(num)
num_9=0
for i in xrange(length):
if num[i]=="9":
num_9+=1
if num_9==length:
q_num=""
for i in xrange(length):
q_num+="0"
q_num="1"+q_num[1:]+"1"
return q_num

if length%2==1:
if num[:length/2]>num[::-1][0:length/2]:
num=num[:length/2]+num[length/2]+num[:length/2][::-1]
else:
if num[length/2]==9:
num=str(int(num[:length/2-1])+1)+num[length/2:-1]
else:
num=str(int(num[:length/2+1])+1)+num[length/2+1:-1]
num=num[:length/2]+num[length/2]+num[:length/2][::-1]
else:
if num[:length/2]>num[::-1][0:length/2]:
num=num[:length/2]+num[:length/2][::-1]
else:
num=str(int(num[:length/2])+1)+num[length/2+1:-1]
num=num[:length/2]+num[:length/2][::-1]

return num

count=int(raw_input())#要处理的数的个数
for i in xrange(count):
t=raw_input()
print palindrome(t)



在他乡奋斗 2009-08-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 litaoye 的回复:]
判断一下该数长度的奇偶,然后截出前半截,生成回文数同该数比较大小,如果大于,则输出生成的回文数,
如果小于,则该数+1生成回文数,重复上面的判断就行,应该只有9999....9的情况需要特殊判断一下。
[/Quote]
顶!挺好的。
绿色夹克衫 2009-08-28
  • 打赏
  • 举报
回复
判断一下该数长度的奇偶,然后截出前半截,生成回文数同该数比较大小,如果大于,则输出生成的回文数,
如果小于,则该数+1生成回文数,重复上面的判断就行,应该只有9999....9的情况需要特殊判断一下。

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧