POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

思路:

这三个题是一个比一个令人纠结呀。

POJ-1077

爆搜可以过,94ms,注意不能用map就是了。

#include<iostream>
#include<stack>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
const int maxn = 500086;
const int inf = 2.1e9;
const int mod = 1e9+7;
const double eps = 1e-6;

int ans=123456780;
char mp[5][5];

int Head[maxn];
int viss[maxn];
int Next[maxn];
int tot;

bool findd(int n)
{
    int s=n%maxn;
    int k=Head[s];
    while(k!=-1){
        if(viss[k]==n){return true;}
        k=Next[k];
//        cout<<k<<endl;
    }
    tot++;
    Next[tot]=Head[s];
    viss[tot]=n;
    Head[s]=tot;
    return false;

}

int n=3;
int a[10],k;

int mypow(int b)
{
//    int s=1;
//    for(int i=1;i<=b;i++){
//        s*=a;
//    }
//    return s;
    if(b==0){return 1;}
    if(b==1){return 10;}
    if(b==2){return 100;}
    if(b==3){return 1000;}
    if(b==4){return 10000;}
    if(b==5){return 100000;}
    if(b==6){return 1000000;}
    if(b==7){return 10000000;}
    if(b==8){return 100000000;}
//    else if(b==9){return 1000000000;}
}

inline int cal()
{
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(mp[i][j]=='x'){ans*=10;}
            else{ans=ans*10+mp[i][j]-48;}
        }
    }
    return ans;
}

int pre[maxn];
char op[maxn];

inline int up(int num)
{
    if(k<=3){return -1;}
    int t=k-3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

inline int down(int num)
{
    if(k>=7){return -1;}
    int t=k+3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}


inline int left(int num)
{
    if(k==1||k==4||k==7){return -1;}
    int t=k-1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

inline int right(int num)
{
    if(k==3||k==6||k==9){return -1;}
    int t=k+1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

void getf(int t)
{
    for(int i=9;i>=1;i--){
        a[i]=t%10;
        t/=10;
        if(a[i]==0){k=i;}
    }
}

int bfs()
{
    queue<int>q;
    queue<int>qq;
    q.push(cal());
    qq.push(-1);
    int pos=1;
    int ah;
    int ss,num,t;
    while(!q.empty()){
        num=q.front();
        ss=qq.front();
        qq.pop();
        q.pop();
        getf(num);
        t=up(num);
        if(t==ans){pre[pos]=ss;op[pos]='u';return pos;}
        if(t!=-1&&!findd(t)){
            pre[pos]=ss;
            op[pos]='u';
            q.push(t);
            qq.push(pos);
            pos++;
        }

        t=down(num);

        if(t==ans){pre[pos]=ss;op[pos]='d';return pos;}
        if(t!=-1&&!findd(t)){
            pre[pos]=ss;
            op[pos]='d';
            q.push(t);
            qq.push(pos);
            pos++;
        }

        t=left(num);
        if(t==ans){pre[pos]=ss;op[pos]='l';return pos;}
        if(t!=-1&&!findd(t)){
            pre[pos]=ss;
            op[pos]='l';
            q.push(t);
            qq.push(pos);
            pos++;
        }

        t=right(num);
        if(t==ans){pre[pos]=ss;op[pos]='r';return pos;}
        if(t!=-1&&!findd(t)){
            pre[pos]=ss;
            op[pos]='r';
            q.push(t);
            qq.push(pos);
            pos++;
        }
    }
    return -1;
}


int main()
{
    ios::sync_with_stdio(false);

//    while(cin>>)
    memset(Head,-1,sizeof(Head));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>mp[i][j];
        }
    }

    if(cal()==ans){cout<<"lr"<<endl;return 0;}
    int k=bfs();
    stack<char>sss;
    while(k>0){
        sss.push(op[k]);
        k=pre[k];
    }
    while(!sss.empty()){
        cout<<sss.top();
        sss.pop();
    }
    cout<<endl;
    return 0;
}

HDU -1043

预处理打表,注意要逆向。

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#define fuck(x) /*cout<<#x<<" = "<<x<<endl;*/;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5000086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1e9+7;
const double eps = 1e-6;

int anss=123456780;
int fac[10];
void getfac()
{
    fac[0]=1;
    for(int i=1;i<=9;i++){
        fac[i]=fac[i-1]*i;
    }
}


int KT(int numi)
{
    ll ans=0;
    int op[10];
    int s=numi;
    for(int i=9;i>=1;i--){
        op[i]=numi%10;
//        if(op[i]==0){op[i]=9;}
        numi/=10;
    }
    for(int i=1;i<=9;i++){
        int sum=0;
        for(int j=i+1;j<=9;j++){
            if(op[j]<op[i]){sum++;}
        }
        ans+=sum*fac[9-i];
    }
//    if(ans+1==92307){cout<<"__"<<s<<endl;}
    return ans+1;
}
int a[15],k;
void getf(int t)
{
    for(int i=9;i>=1;i--){
        a[i]=t%10;
        t/=10;
        if(a[i]==0){k=i;}
    }
}
int mypow(int b)
{
    if(b==0){return 1;}
    if(b==1){return 10;}
    if(b==2){return 100;}
    if(b==3){return 1000;}
    if(b==4){return 10000;}
    if(b==5){return 100000;}
    if(b==6){return 1000000;}
    if(b==7){return 10000000;}
    if(b==8){return 100000000;}
}

int up(int num)
{
    if(k<=3){return num;}
    int t=k-3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int down(int num)
{
    if(k>=7){return num;}
    int t=k+3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int left(int num)
{
    if(k==1||k==4||k==7){return num;}
    int t=k-1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int right(int num)
{
    if(k==3||k==6||k==9){return num;}
    int t=k+1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}


int ans[maxn];
int ord[maxn];
char op[maxn];
struct node
{
    int num,s;
};
void bfs()
{
    queue<node>q;
    q.push(node{anss,0});
    int pos=1;
    node exa;
    int t,kt;
    ans[KT(anss)]=pos;pos++;
    while(!q.empty()){
        exa=q.front();
        q.pop();
        int num=exa.num;
        getf(num);
        fuck(num)


        t=up(num);
        kt=KT(t);
        fuck(t)
        if(!ans[kt]){
//            cout<<"_"<<endl;
            ans[kt]=pos;fuck(pos);
            fuck(exa.s);
            ord[pos]=exa.s;
            q.push(node{t,pos});
            op[pos]='d';
            pos++;
        }

        t=down(num);
        fuck(t)
        kt=KT(t);

        if(!ans[kt]){
//            cout<<"_"<<endl;
            ans[kt]=pos;
            fuck(pos);
            fuck(exa.s);
            ord[pos]=exa.s;
            q.push(node{t,pos});
            op[pos]='u';
            pos++;
        }


        t=left(num);
        fuck(t)
        kt=KT(t);
        if(!ans[kt]){
//            cout<<"_"<<endl;
            fuck(pos);
            fuck(exa.s);
            fuck(kt);
            ans[kt]=pos;
            ord[pos]=exa.s;
            q.push(node{t,pos});
            op[pos]='r';
            pos++;
        }

        t=right(num);
        fuck(t)
        kt=KT(t);
        if(!ans[kt]){
//            cout<<"_"<<endl;
            ans[kt]=pos;
            fuck(pos);
            fuck(exa.s);
            ord[pos]=exa.s;
            q.push(node{t,pos});
            op[pos]='l';
            pos++;
        }

    }
}

char mp[10][10];
int main()
{
    ios::sync_with_stdio(false);
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    getfac();
    int hh=0;;
    bfs();

//    for(int i=1;i<=100;i++){
//        cout<<i<<": "<<ord[i]<<
//    }

    for(int i=1;i<=10;i++){
        fuck(ord[i]);
        fuck(op[i]);
    }

    while(cin>>mp[1][1]){
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                if(i==1&&j==1){continue;}
                cin>>mp[i][j];
            }
        }
        int cnt=0;
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                if(mp[i][j]=='x'){cnt*=10;}
                else{cnt=cnt*10+mp[i][j]-48;}
            }
        }
//        cout<<cnt<<endl;
//        cout<<KT(cnt)<<endl;
        int kk=ans[KT(cnt)];
        if(kk==0){printf("unsolvable\n");}
        else{
            while(kk){
                printf("%c",op[kk]);
//                cout<<kk<<" "<<op[kk]<<endl;
                kk=ord[kk];
            }
            printf("\n");
        }
    }
//    system("pause");
    return 0;
}

HDU 3567

这个按顺序预处理,我曾试图使用优先队列,控制一下字典序,但是会超时,看其他的题解都没有这样做,于是我就直接跑,没有管这些了,当然在bfs的时候还是要按照dlru来进行搜索的。

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 4000086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1e9+7;
const double eps = 1e-6;

int fac[15];
void getfac()
{
    fac[0]=1;
    for(int i=1;i<=9;i++){
        fac[i]=fac[i-1]*i;
    }
}

int mypow(int b)
{
    if(b==0){return 1;}
    if(b==1){return 10;}
    if(b==2){return 100;}
    if(b==3){return 1000;}
    if(b==4){return 10000;}
    if(b==5){return 100000;}
    if(b==6){return 1000000;}
    if(b==7){return 10000000;}
    if(b==8){return 100000000;}
}

int a[100],k;
int anss[10]={0,12345678,102345678,120345678
             ,123045678,123405678,123450678
             ,123456078,123456708,123456780};


int up(int num)
{
    if(k<=3){return num;}
    int t=k-3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int down(int num)
{
    if(k>=7){return num;}
    int t=k+3;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int left(int num)
{
    if(k==1||k==4||k==7){return num;}
    int t=k-1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}

int right(int num)
{
    if(k==3||k==6||k==9){return num;}
    int t=k+1;
    num+=a[t]*mypow(9-k);
    num-=a[t]*mypow(9-t);
    return num;
}


void getf(int t)
{
    for(int i=9;i>=1;i--){
        a[i]=t%10;
        t/=10;
        if(a[i]==0){k=i;}
    }
}

int KT(int numi)
{
    ll ans=0;
    int op[10];
    int s=numi;
    for(int i=9;i>=1;i--){
        op[i]=numi%10;
        numi/=10;
    }
    for(int i=1;i<=9;i++){
        int sum=0;
        for(int j=i+1;j<=9;j++){
            if(op[j]<op[i]){sum++;}
        }
        ans+=sum*fac[9-i];
    }
    return ans+1;
}

int ans[10][maxn];
int pre[10][maxn];
char op[10][maxn];
struct node
{
    int num,s;
};
void bfs(int ind)
{
    queue<node>q;
    q.push(node{anss[ind],0});
    int pos=1;
    node exa;
    int t,kt;
    ans[ind][KT(anss[ind])]=pos;pos++;
    while(!q.empty()){
        exa=q.front();
        q.pop();
        int num=exa.num;
        getf(num);
        t=down(num);
        kt=KT(t);
        if(!ans[ind][kt]){
            ans[ind][kt]=pos;
            pre[ind][pos]=exa.s;
            q.push(node{t,pos});
            op[ind][pos]='d';
            pos++;
        }

        t=left(num);
        kt=KT(t);
        if(!ans[ind][kt]){
            ans[ind][kt]=pos;
            pre[ind][pos]=exa.s;
            q.push(node{t,pos});
            op[ind][pos]='l';
            pos++;
        }

        t=right(num);
        kt=KT(t);
        if(!ans[ind][kt]){
            ans[ind][kt]=pos;
            pre[ind][pos]=exa.s;
            q.push(node{t,pos});
            op[ind][pos]='r';
            pos++;
        }

        t=up(num);
        kt=KT(t);
        if(!ans[ind][kt]){
            ans[ind][kt]=pos;
            pre[ind][pos]=exa.s;
            q.push(node{t,pos});
            op[ind][pos]='u';
            pos++;
        }
    }
}
char s1[15],s2[15];

int numm(char *ss)
{
    int ans=0;
    for(int i=1;i<=9;i++){
        if(ss[i]=='X'){ans*=10;}
        else ans=ans*10+ss[i]-48;
    }
    return ans;
}

int change()
{
    int pos=0;
    for(int i=1;i<=9;i++){
        if(s2[i]=='X'){pos=i;}
    }
    char temp[15];
    strcpy(temp+1,s1+1);
    int v=0;
    for(int i=1;i<=9;i++){
        if(s2[i]=='X'){continue;}
        v++;
        for(int j=1;j<=9;j++){
            if(temp[j]==s2[i]){s1[j]=v+48;break;}
        }
        s2[i]=v+48;
    }
    return pos;
}

int main()
{
//    ios::sync_with_stdio(false);
//    freopen("in.txt","r",stdin);
    getfac();
    for(int i=1;i<=9;i++){
        bfs(i);
    }

    int T;
    scanf("%d",&T);
    int cases=0;
    while(T--){
        scanf("%s%s",s2+1,s1+1);
        cases++;
        printf("Case %d: ",cases);
        int j=change();
        stack<char>q;
        int t1,t2;
        t1=numm(s1);
        int kk=ans[j][KT(t1)];
        if(kk==1){printf("0\n\n");}
        else{
            while(kk){
                q.push(op[j][kk]);
                kk=pre[j][kk];
            }
            printf("%d\n",q.size());
            while(!q.empty()){
                printf("%c",q.top());
                q.pop();
            }
            printf("\n");
        }
    }
    return 0;
}

 

posted @ 2018-09-06 20:54  断腿三郎  阅读(279)  评论(0编辑  收藏  举报