SPOJ 5 The Next Palindrome

题目大意就是给出一个数,就比他大的最近的一个回文数,而数据范围到了10^1000000,所以暴搜之类的肯定不行的。

所以就要用字符串处理了。

首先如果输入数包含的数字全是9的话,那么显然应该输出100......0001这样的数,也只有这个情况会出现结果比输入的长度增1。

然后输入的是个位数的话,就输出下一个个位数就行,当然了,9除外。

然后就要把整个数字分为左右两半部分,从中间开始,用左边的数字分别与右边相对位置的数字比较,只要一出现大于的,后面的就不用判断了,那么就表明了用左边这个数字复制到右边,必然比原来那个数大,那么,只要一出现小于的,同样的道理。然后还有一种是本身是回文数的,就是左右一直相等呗。

然后如果左边大于右边的,直接把左半部复制到右半部,输出就行了。

其他的,小于的和相等的,就要把最中间的先加1,然后如果有进位,一位一位的往左边进就行了,最后再把左边的复制到右边就行了。


ID DATE USER PROBLEM RESULT TIME MEM LANG
5851068 2011-10-17 06:58:07 wwj The Next Palindrome accepted
editrun
0.14 4.5M

C++

4.3.2


/* ID: sdj22251 PROG: subset LANG: C++ */ #include <iostream> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <cmath> #include <ctime> #define LOCA #define MAXN 500005 #define INF 100000000 #define eps 1e-7 #define L(x) x<<1 #define R(x) x<<1|1 using namespace std; char s[1000005]; char ans[1000005]; int len, ti, tj; bool check(char *str) { int i; for(i = 0; i < len; i++) { if(str[i] != '9') return false; } return true; } bool ls(char *str) { int p1, p2; if(len % 2 == 0) { p1 = len / 2 - 1; p2 = len / 2; } else { p1 = p2 = len / 2; } ti = p1, tj = p2; if(len % 2 == 1) { p1--; p2++; } while(p1 >= 0) { if(str[p1] < str[p2]) return false; else if(str[p1] > str[p2]) return true; p1--; p2++; } return false; } int main() { #ifdef LOCAL freopen("d:/data.in","r",stdin); freopen("d:/data.out","w",stdout); #endif int t, i; scanf("%d", &t); while(t--) { scanf("%s", s); len = strlen(s); int cnt = 0; if(len == 1 && s[0] < '9') {s[0]++; printf("%s\n", s); continue;} if(check(s)) { printf("1"); for(i = 0; i < len - 1; i++) printf("0"); printf("1\n"); continue; } if(len % 2 == 0) { for(i = 0; i < len / 2; i++) ans[cnt++] = s[i]; for(i = len / 2 - 1 ; i >= 0; i--) ans[cnt++] = s[i]; ans[cnt++] = '\0'; } else { for(i = 0; i <= len / 2; i++) ans[cnt++] = s[i]; for(i = len / 2 - 1; i >= 0; i--) ans[cnt++] = s[i]; ans[cnt++] = '\0'; } if(ls(s)) { printf("%s\n", ans); continue; } ans[ti]++; ans[tj] = ans[ti]; if(ans[ti] > '9') while(ans[ti] > '9' && ti >= 0) { ans[ti] = '0'; ans[tj] = ans[ti]; ti--; tj++; ans[ti]++; ans[tj] = ans[ti]; } printf("%s\n", ans); } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值