POJ 1077 八数码问题 练习搜索

来源:互联网 发布:疯狂粤语 粤知一二 编辑:程序博客网 时间:2024/05/16 14:55

简单bfs+康托展开判重,足以过掉。

一会再写 双向 bfs 还有 A* 和 IDA *

#include <stdio.h>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <string.h>#include <stdlib.h>#include <time.h>#include <fstream>#include <stack>using namespace std;#define READ freopen("acm.in","r",stdin)#define ll long long#define PII pair<int,int>#define PDI pair<double,int>#define PDD pair<double,double>#define MII map<int,int>::iterator #define fst first#define sec second#define MS(x,d) memset(x,d,sizeof(x))#define INF 0x3f3f3f3f#define ALL(x) x.begin(),x.end()#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define MAX 500000#define ROOT 0,n-1,1#define PB push_back#define FOR(a,b,c) for(int a=b;a<c;a++)#define MOD 706679#define keyTree (ch[ ch[root][1] ][0])int init;// r l u dint dir[4][2]={0,1,0,-1,-1,0,1,0};int fac[100];struct P{    int s;    int d;};int used[500000];P pre[500000];int cantor(int a){    int num[20];    int res=0;    int used[20];    MS(used,0);    for(int i=9;i>=1;i--)    {        int cnt=0;        int t=a%10;a/=10;        used[t]=1;        for(int j=0;j<t;j++)            if(!used[j])                cnt++;        res+=cnt*fac[i-1];    }    return res;}int end;int compose(int t[]){    int res=0;    for(int i=0;i<9;i++)    {        res=res*10+t[i];    }    return res;}bool bfs(){    MS(used,0);    queue<int> q;    q.push(init);    used[cantor(init)]=1;    while(!q.empty())    {        int s=q.front();        q.pop();        if(s==end)            return true;        int tmp=s;        int state[15];        for(int i=8;i>=0;i--)        {            state[i]=tmp%10;            tmp/=10;        }        int x,y;        for(int i=0;i<9;i++)            if(state[i]==0)            {                x=i/3;                y=i%3;            }        for(int i=0;i<4;i++)        {            int tx=x+dir[i][0];            int ty=y+dir[i][1];            int ts[15];            for(int j=0;j<9;j++)                ts[j]=state[j];            if(tx>=0&&tx<3&&ty>=0&&ty<3)            {                swap(ts[x*3+y],ts[tx*3+ty]);                int curs=compose(ts);                int hash=cantor(curs);                if(!used[hash])                {                    q.push(curs);                    used[hash]=1;                    pre[hash]=(P){s,i};                }            }        }    }    return false;}int main(){    READ;    fac[0]=1;    for(int i=1;i<=10;i++)        fac[i]=fac[i-1]*i;    for(int i=1;i<9;i++)        end=end*10+i;    end*=10;    char t[3];    while(scanf("%s",t)!=EOF)    {        if(t[0]!='x')            init=t[0]-'0';        for(int i=0;i<8;i++)        {            scanf("%s",t);            if(t[0]!='x')                init=init*10+t[0]-'0';            else                init=init*10;        }        if(bfs())        {            stack<int> S;            for(int s=end;s!=init;s=pre[cantor(s)].s)                S.push(pre[cantor(s)].d);            while(!S.empty())            {                int d=S.top();S.pop();                switch(d)                {                    case 0:                        cout<<'r';                        break;                    case 1:                        cout<<'l';                        break;                    case 2:                        cout<<'u';                        break;                    case 3:                        cout<<'d';                        break;                }            }            cout<<endl;        }        else        {            puts("unsolvable");        }    }    return 0;}

A* 

#include <stdio.h>#include <iostream>#include <queue>#include <algorithm>#include <map>#include <vector>#include <cmath>#include <string.h>#include <stdlib.h>#include <time.h>#include <fstream>#include <stack>using namespace std;#define READ freopen("acm.in","r",stdin)#define ll long long#define PII pair<int,int>#define PDI pair<double,int>#define PDD pair<double,double>#define MII map<int,int>::iterator #define fst first#define sec second#define MS(x,d) memset(x,d,sizeof(x))#define INF 0x3f3f3f3f#define ALL(x) x.begin(),x.end()#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define MAX 500000#define ROOT 0,n-1,1#define PB push_back#define FOR(a,b,c) for(int a=b;a<c;a++)#define MOD 706679#define keyTree (ch[ ch[root][1] ][0])int init;// r l u dint dir[4][2]={0,1,0,-1,-1,0,1,0};int fac[100];struct P{    int s;    int d;};struct node{    int s;    int G;    int H;    bool operator < (const node &o) const    {        return (G+H)>(o.G+o.H);    }};int used[500000];P pre[500000];int cantor(int a){    int num[20];    int res=0;    int used[20];    MS(used,0);    for(int i=9;i>=1;i--)    {        int cnt=0;        int t=a%10;a/=10;        used[t]=1;        for(int j=0;j<t;j++)            if(!used[j])                cnt++;        res+=cnt*fac[i-1];    }    return res;}int rev(int a){    int res=0;    int used[20];    for(int i=0;i<9;i++)    {        int t=a%10;a/=10;        used[t]=1;        for(int i=0;i<t;i++)            if(used[i])                res++;    }    return res;}int end;int compose(int t[]){    int res=0;    for(int i=0;i<9;i++)    {        res=res*10+t[i];    }    return res;}bool bfs(){    fill(used,used+500000,INF);    //queue<int> q;    priority_queue<node> q;    q.push((node){init,0,0});    used[cantor(init)]=0;    while(!q.empty())    {        node tn=q.top();        int pahash=cantor(tn.s);        int s=tn.s;        q.pop();        if(s==end)            return true;        int tmp=s;        int state[15];        for(int i=8;i>=0;i--)        {            state[i]=tmp%10;            tmp/=10;        }        int x,y;        for(int i=0;i<9;i++)            if(state[i]==0)            {                x=i/3;                y=i%3;            }        for(int i=0;i<4;i++)        {            int tx=x+dir[i][0];            int ty=y+dir[i][1];            int ts[15];            for(int j=0;j<9;j++)                ts[j]=state[j];            if(tx>=0&&tx<3&&ty>=0&&ty<3)            {                swap(ts[x*3+y],ts[tx*3+ty]);                int curs=compose(ts);                int hash=cantor(curs);                if(used[hash]>used[pahash]+1)                {                    q.push((node){curs,used[pahash]+1,rev(curs)});                    used[hash]=used[pahash]+1;                    pre[hash]=(P){s,i};                }            }        }    }    return false;}int main(){    READ;    fac[0]=1;    for(int i=1;i<=10;i++)        fac[i]=fac[i-1]*i;    for(int i=1;i<9;i++)        end=end*10+i;    end*=10;    char t[3];    while(scanf("%s",t)!=EOF)    {        if(t[0]!='x')            init=t[0]-'0';        for(int i=0;i<8;i++)        {            scanf("%s",t);            if(t[0]!='x')                init=init*10+t[0]-'0';            else                init=init*10;        }        if(bfs())        {            stack<int> S;            for(int s=end;s!=init;s=pre[cantor(s)].s)                S.push(pre[cantor(s)].d);            while(!S.empty())            {                int d=S.top();S.pop();                switch(d)                {                    case 0:                        cout<<'r';                        break;                    case 1:                        cout<<'l';                        break;                    case 2:                        cout<<'u';                        break;                    case 3:                        cout<<'d';                        break;                }            }            cout<<endl;        }        else        {            puts("unsolvable");        }    }    return 0;}


0 0
原创粉丝点击