Generalized Palindromic Number
Time Limit: 2 Seconds Memory Limit: 65536 KB
A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number.
We call a number generalized palindromic number, if after merging all the consecutive same digits, the resulting number is a palindromic number. For example, 122111 is a generalized palindromic number. Because after merging, 122111 turns into 121 which is a palindromic number.
Now you are given a positive integer N, please find the largest generalized palindromic number less than N.
Input
There are multiple test cases. The first line of input contains an integer T (about 5000) indicating the number of test cases. For each test case:
There is only one integer N (1 <= N <= 1018).
Output
For each test case, output the largest generalized palindromic number less than N.
Sample Input
4
12
123
1224
1122
Sample Output
11
121
1221
1121
Author: LIN, Xi Source: The 2014 ACM-ICPC Asia Mudanjiang Regional First Round
转自:http://blog.csdn.net/u011345136/article/details/39122741
题意:求小于N的回文数,这个数的回文相同的数可以缩成一个数
思路:dfs(l, r, flag):l代表左边侧长度,r代表右边的长度,flag代表是否处于边界,然后在搜索右边匹配左边的同时,枚举k,k代表右边连续相同的数都匹配左边的个数
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map> #define N 55
#define M 15
#define mod 6
#define mod2 100000000
#define ll long long
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int T;
ll n;
char s[N];
ll ans;
int len;
char leftnum[N];
char rightnum[N]; void ini()
{
// scanf("%lld",&n);
cin>>n;
ans=-;
//memset(left,0,sizeof(left));
//memset(right,0,sizeof(right));
sprintf(s+,"%lld",n);
//sprintf(s+1,"%I64d",n);
len=strlen(s+);
for(int i=;i<=len;i++){
s[i]-='';
}
} void out()
{
//printf("%lld\n",ans);
cout<<ans<<endl;
} ll getans(int l,int r)
{
ll re=;
int i;
for(i=;i<=l;i++){
re=re*+leftnum[i];
}
for(i=r;i>=;i--){
re=re*+rightnum[i];
}
return re;
} ll dfs(int l,int r,int flag)
{
ll re=-;
int i,k,m;
if(l+r->len) return -1ll;
if(l+r-==len){
re=getans(l-,r);
if(re>=n) return -1ll;
return re;
} m= (flag==) ? s[l] : ;
for(i=m;i>=;i--)
{
leftnum[l]=i;
if( (l== || leftnum[l]!=leftnum[l-]) && !(l== && i==) && (l+r!=len) )
{
for(k=;k+l+r<=len;k++){
rightnum[k+r]=i;
re=max(re,dfs(l+,r+k,flag && (m==i) ) );
}
}
else{
re=max(re,dfs(l+,r,flag && (m==i) ));
}
if(re>){
return re;
}
}
return re;
} int main()
{
//freopen("data.in","r",stdin);
scanf("%d",&T);
for(int cnt=;cnt<=T;cnt++)
// while(T--)
//while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF)
{
ini();
ans=dfs(,,);
out();
} return ;
}