zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Android安装apk
    Android获取应用程序版本信息
    Handler消息传递机制
    Activity的启动模式
    cocopods的使用
    ios9 的新特性
    静态库的制作详解
    真机调试
    时间差计算(给定两时间,转换为时间差)
    socket 通信机制的实现
  • 原文地址:https://www.cnblogs.com/Kiraa/p/5277130.html
Copyright © 2011-2022 走看看