704 - Colour Hash

#include <iostream>
#include <cstdio>
#include <sstream>
#include <memory.h>

using namespace std;
const int MAX=100003;
typedef char State[24];
int head1[MAX],next1[MAX],
    head2[MAX],next2[MAX];
State q1[MAX],q2[MAX],
      ans={0,3,4,3,0,5,6,5,0,1,2,1,0,7,8,7,0,9,10,9,0,1,2,1};
int n,f1,e1,dir1[MAX],dir2[MAX],way1[MAX],way2[MAX],c1[MAX],c2[MAX],
      f2,e2,cross;
bool revFlag;
long long maxVal,ttt;
void step1(State &t){
    int x1=t[11],x2=t[10];
    for(int i=11;i>=2;i--)
        t[i]=t[i-2];
    t[0]=x2;
    t[1]=x1;
    t[23]=t[11];
    t[22]=t[10];
    t[21]=t[9];
}
void step2(State &t){
    int x1=t[12],x2=t[13];
    for(int i=12;i<22;i++)
        t[i]=t[i+2];
    t[22]=x1;
    t[23]=x2;
    t[11]=t[23];
    t[10]=t[22];
    t[9]=t[21];
}
void step3(State &t){
    int x1=t[0],x2=t[1];
    for(int i=0;i<10;i++)
        t[i]=t[i+2];
    t[10]=x1;
    t[11]=x2;
    t[23]=t[11];
    t[22]=t[10];
    t[21]=t[9];
}
void step4(State &t){
    int x1=t[23],x2=t[22];
    for(int i=23;i>13;i--)
        t[i]=t[i-2];
    t[12]=x2;
    t[13]=x1;
    t[11]=t[23];
    t[10]=t[22];
    t[9]=t[21];
}
int hash(const State &t){
    int v=0;
    for(int i=0;i<24;i++){
        v=v*10+t[i];
    }
    v=v%MAX;
    if(v<0)
        v+=MAX;
    return v;
}
bool tryToInsert(const int &x){
    int h=hash(q1[x]),u;
    u=head1[h];
    while(u){
        if(!memcmp(q1[u],q1[x],sizeof(q1[u]))){
            return 0;
        }
        u=next1[u];
    }
    next1[x]=head1[h];
    head1[h]=x;
    return 1;
}
bool tryToInsert2(const int &x){
    int h=hash(q2[x]),u;
    u=head2[h];
    while(u){
        if(!memcmp(q2[u],q2[x],sizeof(q2[u])))
            return 0;
        u=next2[u];
    }
    next2[x]=head2[h];
    head2[h]=x;
    return 1;
}
int find_res(int x){
    int h=hash(q1[x]),u;
    u=head2[h];
    while(u){
        if(!memcmp(q2[u],q1[x],sizeof(q2[u])))
            return u;
        u=next2[u];
    }
    return 0;
}
int find_res2(int x){
    int h=hash(q2[x]),u;
    u=head1[h];
    while(u){
        if(!memcmp(q2[x],q1[u],sizeof(q1[u]))){
            return u;
        }
        u=next1[u];
    }
    return 0;
}
long long  ansRes1(long long x,int s){
    //cout<<"s: "<<s<<" "<<dir1[s]<<endl;
    if(s<=1)
        return x;
    x=ansRes1(x,dir1[s])*10+way1[s];
    return x;
}
long long ansRes2(long long  x,int s){
    if(s<=1)
        return x;
    x=x*10+way2[s];
    return ansRes2(x,dir2[s]);
    //ansRes2(dir2[x]);
}
void bfs(){
    int t;
    memset(head1,0,sizeof(head1));
    memset(next1,0,sizeof(next1));
    memset(head2,0,sizeof(head2));
    memset(next2,0,sizeof(next2));
    memset(dir1,0,sizeof(dir1));
    memset(dir2,0,sizeof(dir2));
    memset(c1,0,sizeof(c1));
    memset(way1,0,sizeof(way1));
    memset(c2,0,sizeof(c2));
    memset(way2,0,sizeof(way2));
    f1=1;
    e1=2;
    f2=1;
    e2=2;
    c1[1]=c2[1]=0;
    memcpy(q2[f2],ans,sizeof(ans));
    tryToInsert(f1);
    tryToInsert2(f2);
    if(find_res2(f2)){
        cross=1;
        return ;
    }
    while(c1[f1]+c2[f2]<16){
        //if(e1-f1<=e2-f2){
        if(c1[f1]<=c2[f2]){
            //cout<<"you"<<endl;
            memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
            step1(q1[e1]);
            if(tryToInsert(e1)){
                dir1[e1]=f1;
                c1[e1]=c1[f1]+1;
                way1[e1]=1;
                t=find_res(e1);
                if(t){
                    cross=1;
                    e2=t;
                    break;
                }
                ++e1;
            }

            memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
            step2(q1[e1]);
            if(tryToInsert(e1)){
                dir1[e1]=f1;
                c1[e1]=c1[f1]+1;
                way1[e1]=2;
                t=find_res(e1);
                if(t){
                    cross=1;
                    e2=t;
                    break;
                }
                ++e1;
            }

            memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
            step3(q1[e1]);
            if(tryToInsert(e1)){
                dir1[e1]=f1;
                c1[e1]=c1[f1]+1;
                way1[e1]=3;
                t=find_res(e1);
                if(t){
                    cross=1;
                    e2=t;
                    break;
                }
                ++e1;
            }
            memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
            step4(q1[e1]);
            if(tryToInsert(e1)){
                dir1[e1]=f1;
                c1[e1]=c1[f1]+1;
                way1[e1]=4;
                t=find_res(e1);
                if(t){
                    cross=1;
                    e2=t;
                    break;
                }
                ++e1;
            }
            f1++;
        }
        else{
            memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
            step3(q2[e2]);
            if(tryToInsert2(e2)){
                dir2[e2]=f2;
                c2[e2]=c2[f2]+1;
                way2[e2]=1;
                t=find_res2(e2);
                if(t){
                    cross=1;
                    revFlag=1;
                    ttt=ansRes2(ansRes1(0,t),e2);
                    if(ttt<maxVal)
                        maxVal=ttt;
                }
                ++e2;
            }
            memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
            step4(q2[e2]);
            if(tryToInsert2(e2)){
                dir2[e2]=f2;
                c2[e2]=c2[f2]+1;
                way2[e2]=2;
                t=find_res2(e2);
                if(t){
                    cross=1;
                    revFlag=1;
                    ttt=ansRes2(ansRes1(0,t),e2);
                    if(ttt<maxVal)
                        maxVal=ttt;
                }
                ++e2;
            }
            memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
            step1(q2[e2]);
            if(tryToInsert2(e2)){
                dir2[e2]=f2;
                c2[e2]=c2[f2]+1;
                way2[e2]=3;
                t=find_res2(e2);
                if(t){
                    //cout<<"t1: "<<way1[t]<<endl;
                    cross=1;
                    revFlag=1;
                    ttt=ansRes2(ansRes1(0,t),e2);
                    if(ttt<maxVal)
                        maxVal=ttt;
                    //break;
                }
                ++e2;
            }
            memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
            step2(q2[e2]);
            if(tryToInsert2(e2)){
                dir2[e2]=f2;
                c2[e2]=c2[f2]+1;
                way2[e2]=4;
                t=find_res2(e2);
                if(t){
                    revFlag=1;
                    cross=1;
                    //e1=t;
                    //cout<<"t4:";
                    ttt=ansRes2(ansRes1(0,t),e2);
                    if(ttt<maxVal)
                        maxVal=ttt;
                    //ansRes1(e1);
                    //ansRes2(e2);
                    //cout<<endl;
                    //break;
                }
                ++e2;
            }
            f2++;
        }
    }
}

int main()
{
    freopen("i.txt","r",stdin);
    freopen("o","w",stdout);
    int t1;
    cin>>n;
    while(n--){
        maxVal=2305843009213693952LL;
        cross=revFlag=0;
        for(int i=0;i<24;i++){
            cin>>t1;
            q1[1][i]=t1;
        }
        bfs();
        if(cross){
            if(!revFlag&&c1[e1]+c2[e2]==0)
                cout<<"PUZZLE ALREADY SOLVED"<<endl;
            else{
                //cout<<"plus: "<<c1[f1]<<endl;
                //cout<<c2[f2]<<endl;
                if(!revFlag)
                    cout<<ansRes2(ansRes1(0,e1),e2)<<endl;
                else
                    cout<<maxVal<<endl;
            }
        }
        else{
            cout<<"NO SOLUTION WAS FOUND IN 16 STEPS"<<endl;
        }

    }
    return 0;
}

 

双广+注意判smallest number

你可能感兴趣的:(704 - Colour Hash)