码迷,mamicode.com
首页 > 其他好文 > 详细

[2016-02-24][UVA][1601][The Morning after Halloween]

时间:2016-02-25 22:42:28      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:

[2016-02-24][UVA][1601][The Morning after Halloween]

  • 时间:2016-02-24 15:49:41 星期三
  • 题目编号:UVA 1601
  • 题目大意:给定一个迷宫图,至多3个小写字母和等数目大写字符,求小写字母移动到大写字母的最少步数
  •                 迷宫宽度范围是4~16,字母个数是1~3,
  • 分析:求最少步数,BFS,知道终点状态,可以用双向bfs优化
  • 方法:BFS   

//单向bfs
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
        int t,now[3];
        Node(int _t,int a = -1,int b = -1,int c = -1):t(_t){
                now[0] = a;now[1] = b;now[2]= c;
        }
};
struct Edge{
        int to,nxt;
};
Edge e[2000];
char mp[17][17];
int w,h,n,cnt,head[267];
int goal[3],start[3],vis[268][268][268];
int d[5][2] = {{0,0},{-1,0},{1,0},{0,1},{0,-1}};
void add(int u,int v){
        e[cnt].to = v;
        e[cnt].nxt = head[u];
        head[u] = cnt++;
}
void init(){
        cnt = 0;
        memset(start,-1,sizeof(start));
        memset(goal,-1,sizeof(goal));
        memset(head,-1,sizeof(head));
        for(int i = 0; i < h ;++i){
                for(int j = 0;j < w;++j){
                        if(mp[i][j] == ‘#‘)     continue;
                        if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘c‘)
                                        start[ mp[i][j] - ‘a‘ ] = i*w + j;
                        if(mp[i][j] >= ‘A‘ && mp[i][j] <= ‘C‘)
                                        goal[ mp[i][j] - ‘A‘ ] = i*w + j;
                        for(int k = 0;k < 5;++k){
                                int ni = i + d[k][0],nj = j + d[k][1];
                                if(ni >= 0 && ni < h && nj >=0 && nj<w && mp[ni][nj]!=‘#‘)
                                        add(i*w+j,ni*w+nj);
                        }
                }
        }
}
int bfs(){
        queue<Node> q;
        memset(vis,0,sizeof(vis));
        vis[start[0]+10][start[1]+10][start[2]+10] = 1;
        q.push(Node(0,start[0],start[1],start[2]));
        while(!q.empty()){
                Node u = q.front();q.pop();
                if(memcmp(u.now,goal,sizeof(goal)) == 0)
                        return u.t;
                       
                if(n==1){
                        for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                Node nxt=u;
                                nxt.now[0]=e[i].to;
                                if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                                vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                                nxt.t=u.t+1;
                                q.push(nxt);
                        }
                }else if(n==2){
                        for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                Node nxt=u;
                                nxt.now[0]=e[i].to;
                                for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                                        nxt.now[1]=e[j].to;
                                        if(nxt.now[0]==nxt.now[1])  continue;
                                        if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                                        vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                                        nxt.t=u.t+1;
                                        q.push(nxt);
                                }
                        }
                }else{
                        for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                Node nxt=u;
                                nxt.now[0]=e[i].to;
                                for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                                        nxt.now[1]=e[j].to;
                                        if(nxt.now[0]==nxt.now[1])  continue;
                                        if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                                        for(int k=head[u.now[2]];k!=-1;k=e[k].nxt){
                                                nxt.now[2]=e[k].to;
                                                if(nxt.now[2]==nxt.now[0]||nxt.now[2]==nxt.now[1])  continue;
                                                if(nxt.now[2]==u.now[0]&&nxt.now[0]==u.now[2])  continue;
                                                if(nxt.now[2]==u.now[1]&&nxt.now[1]==u.now[2])  continue;
                                                if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10])    continue;
                                                vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=1;
                                                nxt.t=u.t+1;
                                                q.push(nxt);
                                        }
                                }
                        }
                }
        }
        return -1;
}
int main(){
        while(scanf("%d%d%d",&w,&h,&n) != EOF && (w || h || n)){
                getchar();
                for(int i = 0;i < h ; i++)      gets(mp[i]);
                init();
                printf("%d\n",bfs());
        }
        return 0;
}  

//双向bfs
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
        int t,now[3];
        Node(int _t,int a = -1,int b = -1,int c = -1):t(_t){
                now[0] = a;now[1] = b;now[2]= c;
        }
};
struct Edge{
        int to,nxt;
};
Edge e[2000];
char mp[17][17];
int w,h,n,cnt,head[267];
int goal[3],start[3],vis[268][268][268];
int d[5][2] = {{0,0},{-1,0},{1,0},{0,1},{0,-1}};
void add(int u,int v){
        e[cnt].to = v;
        e[cnt].nxt = head[u];
        head[u] = cnt++;
}
void init(){
        cnt = 0;
        memset(start,-1,sizeof(start));
        memset(goal,-1,sizeof(goal));
        memset(head,-1,sizeof(head));
        for(int i = 0; i < h ;++i){
                for(int j = 0;j < w;++j){
                        if(mp[i][j] == ‘#‘)     continue;
                        if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘c‘)
                                        start[ mp[i][j] - ‘a‘ ] = i*w + j;
                        if(mp[i][j] >= ‘A‘ && mp[i][j] <= ‘C‘)
                                        goal[ mp[i][j] - ‘A‘ ] = i*w + j;
                        for(int k = 0;k < 5;++k){
                                int ni = i + d[k][0],nj = j + d[k][1];
                                if(ni >= 0 && ni < h && nj >=0 && nj<w && mp[ni][nj]!=‘#‘)
                                        add(i*w+j,ni*w+nj);
                        }
                }
        }
}
int bfs(){
        queue<Node> q[2];
        memset(vis,0,sizeof(vis));
        vis[start[0]+10][start[1]+10][start[2]+10] = 1;
        vis[goal[0]+10][goal[1]+10][goal[2]+10] = 2;
        q[0].push(Node(0,start[0],start[1],start[2]));
        q[1].push(Node(0,goal[0],goal[1],goal[2]));
        int cur = 1,visflg[2] = {1,2};
        while(!q[0].empty() || !q[1].empty()){
                cur ^= 1;
                int curct = q[cur].front().t;
                while(!q[cur].empty() && q[cur].front().t == curct){
                        Node u = q[cur].front();q[cur].pop();
                        if(n==1){
                                for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                        Node nxt=u;
                                        nxt.now[0]=e[i].to;
                                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])
                                                return u.t + q[cur^1].front().t + 1;
                                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;
                                        vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];
                                        nxt.t=u.t+1;
                                        q[cur].push(nxt);
                                }
                        }else if(n==2){
                                for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                        Node nxt=u;
                                        nxt.now[0]=e[i].to;
                                        for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                                                nxt.now[1]=e[j].to;
                                                if(nxt.now[0]==nxt.now[1])  continue;
                                                if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                                                if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])
                                                        return u.t + q[cur^1].front().t + 1;
                                                if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;
                                                vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];
                                                nxt.t=u.t+1;
                                                q[cur].push(nxt);
                                        }
                                }
                        }else{
                                for(int i=head[u.now[0]];i!=-1;i=e[i].nxt){
                                        Node nxt=u;
                                        nxt.now[0]=e[i].to;
                                        for(int j=head[u.now[1]];j!=-1;j=e[j].nxt){
                                                nxt.now[1]=e[j].to;
                                                if(nxt.now[0]==nxt.now[1])  continue;
                                                if(nxt.now[0]==u.now[1]&&nxt.now[1]==u.now[0])    continue;
                                                for(int k=head[u.now[2]];k!=-1;k=e[k].nxt){
                                                        nxt.now[2]=e[k].to;
                                                        if(nxt.now[2]==nxt.now[0]||nxt.now[2]==nxt.now[1])  continue;
                                                        if(nxt.now[2]==u.now[0]&&nxt.now[0]==u.now[2])  continue;
                                                        if(nxt.now[2]==u.now[1]&&nxt.now[1]==u.now[2])  continue;
                                                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur^1])
                                                                return u.t + q[cur^1].front().t + 1;
                                                        if(vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10] == visflg[cur])    continue;
                                                        vis[nxt.now[0]+10][nxt.now[1]+10][nxt.now[2]+10]=visflg[cur];
                                                        nxt.t=u.t+1;
                                                        q[cur].push(nxt);
                                                }
                                        }
                                }
                        }
                }
        }
        return -1;
}
int main(){
        while(scanf("%d%d%d",&w,&h,&n) != EOF && (w || h || n)){
                getchar();
                for(int i = 0;i < h ; i++)      gets(mp[i]);
                init();
                printf("%d\n",bfs());
        }
        return 0;
}  























[2016-02-24][UVA][1601][The Morning after Halloween]

标签:

原文地址:http://www.cnblogs.com/qhy285571052/p/5218499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!