ZOJ Problem Set - 3816 Generalized Palindromic Number 搜索+贪心

来源:互联网 发布:淘宝虚拟物品自动发货 编辑:程序博客网 时间:2024/05/21 22:27

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

1112112211121

  网络赛第一场的H题,比赛的时候想前面一半应该不是相等就是减一,然后再递归去做,但是又感觉很复杂,赛后看别人的代码,有很长的,也有一种是搜索,比较短,看了后觉得这个方法挺好。

  思路是从大到小枚举左边,左边不能超过N的左边,左边枚举的当前位如果和上一位不相等,右边就也需要添加这个数,因为必须保证是这种回文串。右边添加几个呢,暴力枚举搜索所有可能个数,最后这个串的长度和N的长度相等时,把左边和右边合并,看得到的这个数是否比N小(因为左边部分不超过N的左边部分不代表左右合并的串小于N)。因为左边是从大到小枚举的,所以一旦找到符合的就返回。搜索过程中eq表示之前是否达到临界,如果达到了这一位就只能取str[l],没达到可以取9。

 

#include<iostream>#include<queue>#include<cstring>#include<cstdio>#include<cmath>#include<set>#include<map>#include<vector>#include<stack>#include<algorithm>#define INF 0x3f3f3f3f#define eps 1e-9#define MAXN 25#define MAXM 200010#define MAXNODE 50010#define MOD 999983#define SIGMA_SIZE 4typedef long long LL;using namespace std;int T,len,lnum[MAXN],rnum[MAXN];char str[MAXN];LL N;LL getnum(int l,int r){    LL ret=0;    for(int i=0;i<l;i++) ret=ret*10+lnum[i];    for(int i=r-1;i>=0;i--) ret=ret*10+rnum[i];    if(ret<N) return ret;    return -1;}LL DFS(int l,int r,int eq){    if(l+r>=len) return getnum(l,r);    LL ret=-1;    int m=eq?str[l]-'0':9;    for(int i=m;i>=0;i--){        lnum[l]=i;        if((!l||lnum[l]!=lnum[l-1])&&(i||l)&&(l+r+1<len)){            for(int k=1;l+r+k<=len;k++){                rnum[r+k-1]=i;                ret=max(ret,DFS(l+1,r+k,eq&&i==m));            }        }        else ret=max(ret,DFS(l+1,r,eq&&i==m));        if(ret!=-1) return ret;    }    return ret;}int main(){    //freopen("in.txt","r",stdin);    scanf("%d",&T);    while(T--){        scanf("%lld",&N);        sprintf(str,"%lld",N);        len=strlen(str);        printf("%lld\n",DFS(0,0,1));    }    return 0;}


0 0
原创粉丝点击