zoj 3816 Generalized Palindromic Number (根据对称性来搜)

来源:互联网 发布:从零开始学linux编程 编辑:程序博客网 时间:2024/05/29 05:55
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 thanN.

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 thanN.

Sample Input

41212312241122

Sample Output


11
121
1221
1121


题意:
找一个小于n的最大的回文数(连续的相同的数合并之后是回文数)

思路:
比赛一直一维是数位dp,汗,一直不知道怎么写都不知道换思路,思维还是傻傻的。
因为只要找到最大的,所以还是蛮快可以搜出来的,要满足这个回文性质的话,方法是根据对称性来搜。
dfs(le,ri,limit); 左边放了多少个,右边放了多少个,是否有上界标志。
枚举左边这一位放什么(从大到小),再枚举右边和它匹配的长度,dfs下去就行了。
如果左边放i时有结果了,那么这个结果就是最大的了,不用再搜了。
处理小于n的方法是,更新答案时如果>=n的话就不用它更新。

代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#define maxn 401#define MAXN 200005#define INF 0x3f3f3f3f#define mod 1000000007#define eps 1e-6const double pi=acos(-1.0);typedef long long ll;using namespace std;ll n,m,ans;int tot,dig[20],le[20],ri[20];ll get(int num1,int num2){    int i;    ll res=0;    for(i=1;i<=num1;i++)    {        res=res*10+le[i];    }    for(i=num2;i>=1;i--)    {        res=res*10+ri[i];    }    return res;}ll dfs(int num1,int num2,int limit){    ll t,res=0;    if(num1+num2>tot)    {        res=get(num1-1,num2);        if(res<m) return res;        return 0;    }    int i,j,ed;    ed=limit?dig[tot-num1+1]:9;    for(i=ed;i>=0;i--)    {        le[num1]=i;        if((num1==1||le[num1]!=le[num1-1])&&!(num1==1&&i==0)&&(num1+num2<tot))        {            for(j=1; num1+num2+j<=tot; j++) // r与之匹配的个数            {                ri[num2+j]=i;                t=dfs(num1+1,num2+j,limit&&(i==ed));                res=max(res,t);            }        }        else        {            t=dfs(num1+1,num2,limit&&(i==ed));            res=max(res,t);        }        if(res>0) return res;    }    return res;}void solve(){    int i,j;    tot=0;    m=n;    while(n)    {        dig[++tot]=n%10;        n/=10;    }    ans=dfs(1,0,1);    printf("%lld\n",ans);}int main(){    int i,j,t;    scanf("%d",&t);    while(t--)    {        scanf("%lld",&n);        solve();    }    return 0;}
0 0
原创粉丝点击