HDU 1401 双向状态搜索

来源:互联网 发布:清华软件学院排名 编辑:程序博客网 时间:2024/06/06 00:43

第一次写双向状态搜索,输得这么惨,控制不了时间,有很多浪费的时间,不知道如何去控制,代码拍过三遍,最后一遍算是成功的,可是肯定超时,不知道如何优化它。。

只有等以后实力提高了再来搞定它。。

我得理解,每种状态有16种后继状态,可是当跳跃到下一步的时候,却写不出o(1)的判断,最后就成16*o(4) = 64;这样写不超时才叫怪事。。。搞了我三天了。。

贴上神牛的代码:

#pragma warning (disable:4786)#include<stdio.h>#include<queue>#include<map>using namespace std;typedef struct p{    int x,y;}Point;//共有四颗棋子,棋盘大小为64,采用位棋盘表示typedef struct Map{    unsigned __int64 value;    Point p[4];    int steps,which;void getvalue(){//棋盘对应键值value=0;for(short i=0;i<4;i++)value+=(unsigned __int64)1<<((p[i].x-1)*8+(p[i].y-1));}}Map;struct Cmp{bool operator () (const Map &a,const Map &b) const{return a.value<b.value;}};map<Map,int,Cmp>m;queue<Map>q;Map start,end;int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};bool Next(Map cur,Map &next,int ith,int d){//获取第ith个棋子d方向上的下一个棋面状态    int i,j;    next.p[ith].x=cur.p[ith].x+dir[d][0];    next.p[ith].y=cur.p[ith].y+dir[d][1];        if(next.p[ith].x<1||next.p[ith].x>8||next.p[ith].y<1||next.p[ith].y>8)        return false;    for(i=1;i<4;i++){        if(next.p[ith].x==cur.p[(ith+i)%4].x&&next.p[ith].y==cur.p[(ith+i)%4].y){            next.p[ith].x+=dir[d][0];            next.p[ith].y+=dir[d][1];            if(next.p[ith].x<1||next.p[ith].x>8||next.p[ith].y<1||next.p[ith].y>8)                return false;            for(j=1;j<4;j++){                if(next.p[ith].x==cur.p[(ith+j)%4].x                    &&next.p[ith].y==cur.p[(ith+j)%4].y)                    return false;            }            return true;        }    }    return true;}bool bfs(){//双向搜索    Map cur,next;    int i,d,k,v;    m.clear();while(!q.empty()) q.pop();start.steps=end.steps=0;start.which=1;end.which=2;start.getvalue();end.getvalue();m[start]=1;m[end]=2;q.push(start);q.push(end);    while(!q.empty()){        cur=q.front(); q.pop();v=m[cur];if(cur.steps>4)break;if(v!=0&&v!=cur.which)return true;        for(i=0;i<4;i++){//每一颗棋子            for(d=0;d<4;d++){//每一个方向                if(Next(cur,next,i,d)){                    for(k=1;k<4;k++)                        next.p[(i+k)%4]=cur.p[(i+k)%4];                    next.steps=cur.steps+1;next.which=cur.which;                    next.getvalue();if(next.steps>4) continue;v=m[next];                    if(v==next.which) continue;if(v&&v!=next.which) return true;                    m[next]=next.which;                    q.push(next);                }            }        }    }    return false;}int main(){    int i;while(1){for(i=0;i<4;i++){if(scanf("%d%d",&start.p[i].x,&start.p[i].y)==EOF)return 0;}for(i=0;i<4;i++)scanf("%d%d",&end.p[i].x,&end.p[i].y);printf(bfs()?"YES/n":"NO/n");}    return 0;}

也附上我自己超时的代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<queue>using namespace std;struct node {    int x[4],y[4];};queue<node>que;int temp[8][8][8][8][8][8][8][8];int s[8][8][8][8][8][8][8][8];int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};void init(){    while(!que.empty()) que.pop();    memset(temp,0,sizeof(temp));    memset(s,0,sizeof(s));}int judge(node te){    if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>=6){        if(temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>8){             cout<<"NO"<<endl;            return 1;        }            else { cout<<"YES"<<endl; return 1; }    }    if(temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>4) {        cout<<"NO"<<endl; return 1;    }    return 0;} int fan(node te){    for(int i=0;i<4;i++){ ////枚举每个棋子        for(int j=0;j<4;j++){ ////枚举四个方向             node p=te;            p.x[i] += dir[j][0];            p.y[i] += dir[j][1];            if(p.x[i]<0 || p.y[i]>=8) continue;            int flag=0;            for(int r=0;r<4;r++){////判断是否有棋子和它重合????超时根源                 if(p.x[i]==p.x[r] && p.y[i]==p.y[r] && i!=r){                    p.x[i]+=dir[j][0];////再向前移一个位置                     p.y[i]+=dir[j][1];                    if(p.x[i]<0 || p.y[i]>=8){ flag=1; break; }                    for(int k=0;k<4;k++) ///判断是否还有棋子和它重合  ????超时根源                        if(p.x[i]==p.x[k] && p.y[i]==p.y[k] && i!=k) flag=1;                    if(flag) break;                     if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态重合了                        ==s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {                       flag=1; break;                    }                        if(!s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]){///状态没有重合                        s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]= ////标记传递                        s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];                          temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加                        temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;                       int ss = judge(p);                       if(ss) return 1;                        que.push(p);                       flag=1; break;                    }                    if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态不同                        !=s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {                       s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]] *=                       s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];                       temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加                        temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;                       int ss = judge(p);                        if(ss) return 1;                       flag=1; break;                    }                 }            }            if(flag) continue;             if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态重合了                 ==s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {                continue;            }                if(!s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]){///状态没有重合                 s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]= ////标记传递                     s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];                       temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加                     temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;                    int ss = judge(p);                    if(ss) return 1;                     que.push(p);                    continue;            }            if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态不同                 !=s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {                    s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]] *=                    s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];                    temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加                     temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;                    int ss = judge(p);                     if(ss) return 1;                    continue;            }         }    }    return 0;}void BFS(){    while(!que.empty()){        node te=que.front();        que.pop();        if(judge(te)) break;        int flag = fan(te);        if(flag) break;    }}int main(){    int x[4],y[4],a[4],b[4];    while(cin>>x[0]>>y[0]>>x[1]>>y[1]>>x[2]>>y[2]>>x[3]>>y[3]){        for(int i=0;i<4;i++)            cin>>a[i]>>b[i];        for(int i=0;i<4;i++)            x[i]--,y[i]--,a[i]--,b[i]--;        init();        temp[x[0]][y[0]][x[1]][y[1]][x[2]][y[2]][x[3]][y[3]]=1;        temp[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]=1;        s[x[0]][y[0]][x[1]][y[1]][x[2]][y[2]][x[3]][y[3]]=2;/////第一个元素         if(!s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]])////处理标记             s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]=3;        else s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]*=3;        node te;        for(int i=0;i<4;i++){            te.x[i]=x[i];            te.y[i]=y[i];        }        que.push(te);        for(int i=0;i<4;i++){            te.x[i]=a[i];            te.y[i]=b[i];        }        que.push(te);        BFS();    }}/*4 4 4 5 5 4 6 54 4 4 5 5 4 6 54 4 4 5 5 4 6 52 4 3 3 3 6 4 6*/