UVa1601

解题思路:

1.注意到2*2方格中必有一个#,那么最多只有192条通道,可以将所有非‘#’的位置提取出来用邻接表的方式建图,通过bfs搜索目标位置。

2.将三个ghost的位置(a,b,c)作为状态量存储,如果采用邻接矩阵方式存储图,那么转移代价为5*5*5,很容易超时。分析题意可以知道图中结点大部分不是4个方向都能通过,用邻接表可以避免做多余的判断。

代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cctype>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 using namespace std;
  9 const int maxv=192;
 10 
 11 int di[5]={1,-1,0,0,0};
 12 int dj[5]={0,0,1,-1,0};
 13 
 14 int vis[maxv+2][maxv+2][maxv+2];
 15 typedef struct {
 16     int p[3]={0};
 17     int dist=0;
 18 }state;
 19 
 20 vector<int> G[maxv+2];
 21 char buff[20][20];
 22 int id[20][20];
 23 
 24 int w,h,n,vn,ans;
 25 int ghost_ascii[3];
 26 state ghost_init_pos,ghost_target_pos;
 27 
 28 int read(){
 29     memset(vis, 0, sizeof vis);
 30     memset(ghost_ascii, 0, sizeof ghost_ascii);
 31     memset(id, 0, sizeof id);
 32     memset(buff, 0, sizeof buff);
 33     memset(ghost_init_pos.p, 0, sizeof ghost_init_pos.p);
 34     memset(ghost_target_pos.p, 0, sizeof ghost_target_pos.p);
 35     scanf("%d%d%d",&w,&h,&n);
 36     if(w==0) return 0;
 37     
 38     fgets(buff[0], 16, stdin);
 39     
 40     for(int i=0;i<h;i++)
 41         fgets(buff[i], 20, stdin);
 42     
 43     vn=0;
 44     for(int i=0;i<h;i++)
 45         for(int j=0;j<w;j++)
 46             if(buff[i][j]!='#'){
 47                 vn++;
 48                 id[i][j]=vn;
 49             }
 50     char ch;
 51     for(int i=0;i<h;i++){
 52         for(int j=0;j<w;j++){
 53             ch=buff[i][j];
 54           
 55             if(ch!='#'){
 56                 int cur=id[i][j];
 57                 
 58                 for(int pos=0;pos<5;pos++){
 59                     int x=i+di[pos],y=j+dj[pos];
 60                     if(x>=0&&x<h&&y>=0&&y<w&&id[x][y]){
 61                         int pre=id[x][y];
 62                         G[cur].push_back(pre);
 63                     }
 64                 }
 65             
 66                 if(islower(ch)){
 67                     for(int k=0;k<n;k++)
 68                         if(!ghost_ascii[k]||ghost_ascii[k]==ch){
 69                             ghost_ascii[k]=ch;
 70                             ghost_init_pos.p[k]=cur;
 71                             break;
 72                         }
 73                 }
 74                 else if(isupper(ch)){
 75                     for(int k=0;k<n;k++){
 76                         if(!ghost_ascii[k]||ghost_ascii[k]==ch+'a'-'A'){
 77                             ghost_ascii[k]=ch+'a'-'A';
 78                             ghost_target_pos.p[k]=cur;
 79                             break;
 80                         }
 81                     }
 82                 }
 83             }
 84         }
 85     }
 86     return 1;
 87 }
 88 bool check(const state& u,const state& u2){
 89     
 90     for(int i=0;i<n;i++)
 91         for(int j=i+1;j<n;j++)
 92             if(u2.p[i]==u2.p[j]) return false;
 93     
 94     for(int i=0;i<n;i++)
 95         for(int j=i+1;j<n;j++)
 96             if(u2.p[i]==u.p[j]&&u2.p[j]==u.p[i]) return false;
 97     return true;
 98 }
 99 void update(queue<state>& q,const state& u,int i,int j=0,int k=0){
100     state u2;
101     u2.p[0]=G[u.p[0]][i];
102     if(n>=2) u2.p[1]=G[u.p[1]][j];
103     if(n==3) u2.p[2]=G[u.p[2]][k];
104     if(!vis[u2.p[0]][u2.p[1]][u2.p[2]]&&check(u, u2)) {
105         vis[u2.p[0]][u2.p[1]][u2.p[2]]=1;
106         u2.dist=u.dist+1;
107         q.push(u2);
108         /*
109         for(int m=0;m<n;m++)
110             cout<<u.p[m]<<" ";
111         cout<<" to ";
112         for(int m=0;m<n;m++)
113             cout<<u2.p[m]<<" ";
114         cout<<u2.dist<<endl;
115          */
116     }
117 }
118 void solve(){
119     queue<state> q;
120     q.push(ghost_init_pos);
121     vis[ghost_init_pos.p[0]][ghost_init_pos.p[1]][ghost_init_pos.p[2]]=1;
122     while(!q.empty()){
123         state u=q.front();q.pop();
124         
125         if(memcmp(u.p,ghost_target_pos.p,sizeof ghost_target_pos.p)==0) {
126             ans=u.dist;
127             break;
128         }
129         for(int i=0;i<G[u.p[0]].size();i++){
130             if(n==1){
131                 update(q, u, i);
132             }
133             else for(int j=0;j<G[u.p[1]].size();j++){
134                 if(n==2){
135                     update(q, u, i,j);
136                 }
137                 else for(int k=0;k<G[u.p[2]].size();k++){
138                     update(q, u, i,j,k);
139                 }
140             }
141         }
142     }
143     printf("%d
",ans);
144 }
145 
146 int main() {
147     while(read()){
148         solve();
149         
150         for(int i=0;i<=maxv;i++)
151             G[i].clear();
152     }
153     
154     return 0;
155 }
原文地址:https://www.cnblogs.com/Kiraa/p/5277130.html