zoj 3816 Generalized Palindromic Number

来源:互联网 发布:带数据的日历插件 编辑:程序博客网 时间:2024/05/29 13:50

        题意:给一个数n,求一个比n小的最大的数,使得这个数把相邻的相同数合并之后,是一个回文数。

        思路:dfs+剪枝。从高位到低位,从9~0尝试填数构造,如果可行就往下搜。dfs的过程也是构造的过程,需要剪枝,写两个函数,一个判断这个可能没构造完成的数是否可能构造出回文,另一个判断往后构造出来的数是否可能小于n,把不符合上面其中一种情况的分支剪掉。。。具体见代码。我写的时候是否可能构造出回文的判断就调试了很久。


#include<iostream>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<string.h>#include<cstdio>using namespace std;#define ll long longint num[20];int ans[20];int len;//判断这个可能尚未构造完成的数,有没有可能是回文数bool judge(int* b,int pos){    if(pos==0)return 1;    int a[20];    memcpy(a,b,len*sizeof(int));    for(int i=1;i<len;i++){        int l=i,r=i;        do{            if(a[l]!=a[r]&&a[r]!=-1)break;            while(l>0&&a[l-1]!=-1&&a[l-1]==a[l])l--;            while(r<len-1&&a[r+1]!=-1&&a[r+1]==a[r])r++;            if(l>0&&r<len-1){                l--;    r++;            }        }while(l!=0&&r!=len-1);        while(r<len-1&&(a[r]==a[r+1]||a[r+1]==-1))r++;        while(l>0&&a[l]==a[l-1])l--;        if(l==0&&r==len-1&&(a[l]==a[r]||a[r]==-1)){            return 1;        }    }    return 0;}//判断a是否小于bbool lessthan(int* a,int* b){    for(int i=0;i<len;i++){        if(a[i]>b[i])return 0;        if(a[i]<b[i])return 1;    }    if(a[len-1]==b[len-1])return 0;    return 1;}bool dfs(int pos,int *a,bool flag){    if(pos==len){        for(int i=0;i<len;i++)ans[i]=a[i];        return 1;    }    int re[20];    for(int i=0;i<len;i++)re[i]=-1;    for(int i=0;i<pos;i++)re[i]=a[i];    int s=9;    if(!flag)s=num[pos];    for(int i=min(s,9);i>=0;i--){        if(!flag){            if(i<num[pos])flag=1;        }        re[pos]=i;        if(judge(re,pos)&&lessthan(re,num)){//只有可能是回文数且小于n的情况下才继续构造            if(dfs(pos+1,re,flag))return 1;        }    }    return 0;}int main(){    int t;    cin>>t;    while(t--){        ll n;        cin>>n;        if(n==1){            cout<<0<<endl;            continue;        }        ll tmp=n;        len=0;        while(tmp){            num[len++]=tmp%10;            tmp/=10;        }        for(int i=0;i<len;i++){            ans[i]=0;        }        reverse(num,num+len);        dfs(0,ans,0);        if(ans[0]==0){            for(int i=1;i<len;i++){                printf("9");            }printf("\n");        }else{            for(int i=0;i<len;i++){                printf("%d",ans[i]);            }printf("\n");        }    }    return 0;}


0 0
原创粉丝点击