zoukankan      html  css  js  c++  java
  • 【POJ】3523 The Morning after Halloween

    1. 题目描述
    $m imes n$的迷宫(最大为$16 imes 16$)包含最多3个点,这些点可以同时向相邻方向移动或保持停止,使用小写字母表示起始位置,使用大写字母表示中止位置。求最少经过多少时间,这些点可以从起始位置移动到对应的终止位置。

    2. 基本思路
    这是很经典的路径搜索问题,一般采用BFS。因为题目说每个$2 imes 2$个子矩阵,都至少有一个点为#,那么起始空白可走的点一定很少,因此,可以预处理这些点可以通过1个时间单位到达的有效位置。这样可以降低$5^3$的总排列。显然,同时对三个点组成的三元组进行状态压缩,这里采用移位。这些做完了,普通的BFS+map就已经可以解出正确解了。但是太慢了。因此,使用双向BFS+map,发现还是超时,原因是map太慢了(而且会随着状态的增加越来越慢)。那么,直接用数组存(注意不要MLE)。直接过了。双向BFS明显地提高了性能。

    3. 代码

      1 /* 3523 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <bitset>
     12 #include <algorithm>
     13 #include <cstdio>
     14 #include <cmath>
     15 #include <ctime>
     16 #include <cstring>
     17 #include <climits>
     18 #include <cctype>
     19 #include <cassert>
     20 #include <functional>
     21 #include <iterator>
     22 #include <iomanip>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,1024000")
     25 
     26 #define sti                set<int>
     27 #define stpii            set<pair<int, int> >
     28 #define mpii            map<int,int>
     29 #define vi                vector<int>
     30 #define pii                pair<int,int>
     31 #define vpii            vector<pair<int,int> >
     32 #define rep(i, a, n)     for (int i=a;i<n;++i)
     33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     34 #define clr                clear
     35 #define pb                 push_back
     36 #define mp                 make_pair
     37 #define fir                first
     38 #define sec                second
     39 #define all(x)             (x).begin(),(x).end()
     40 #define SZ(x)             ((int)(x).size())
     41 #define lson            l, mid, rt<<1
     42 #define rson            mid+1, r, rt<<1|1
     43 #define INF                0x3f3f3f3f
     44 #define mset(a, val)    memset(a, (val), sizeof(a))
     45 
     46 const int maxn = 20;
     47 const int maxm = 150;
     48 int ID[maxn][maxn];
     49 int sz[maxm];
     50 int Move[maxm][5];
     51 int visit[2][maxm][maxm][maxm];
     52 char s[maxn][maxn];
     53 map<char,int> ptb;
     54 queue<int> Q[2];
     55 int dir[5][2] = {
     56     -1, 0, 1, 0, 0, -1, 0, 1, 0,0
     57 };
     58 int n, m, gn;
     59 int st, ed;
     60 
     61 inline bool judge(int x, int y) {
     62     return x<0 || x>=n || y<0 || y>=m || s[x][y]=='#';
     63 }
     64 
     65 void init() {
     66     int cnt = 0;
     67     map<char,int>::iterator iter;
     68     
     69     ptb.clr();
     70     
     71     rep(i, 0, n) {
     72         rep(j, 0, m) {
     73             if (s[i][j] == '#')
     74                 continue;
     75             
     76             ID[i][j] = cnt++;
     77             if (s[i][j] != ' ')
     78                 ptb[s[i][j]] = ID[i][j];
     79         }
     80     }
     81     
     82     rep(i, 0, n) {
     83         rep(j, 0, m) {
     84             if (s[i][j] == '#')
     85                 continue;
     86             
     87             const int& id = ID[i][j];
     88             sz[id] = 1;
     89             Move[id][0] = id;
     90             rep(k, 0, 4) {
     91                 int x = i + dir[k][0];
     92                 int y = j + dir[k][1];
     93                 if (judge(x, y))
     94                     continue;
     95                 
     96                 Move[id][sz[id]++] = ID[x][y];
     97             }
     98         }
     99     }
    100     
    101     st = ed = 0;
    102     
    103     for (char ch='a'; ch<='z'; ++ch) {
    104         iter = ptb.find(ch);
    105         if (iter != ptb.end()) {
    106             st = (st << 8) | iter->sec;
    107             iter = ptb.find(ch-'a'+'A');
    108             #ifndef ONLINE_JUDGE
    109             assert(iter != ptb.end());
    110             #endif
    111             ed = (ed << 8) | iter->sec;
    112         }
    113     }
    114 }
    115 
    116 int bfs1(const int qid) {
    117     int cst, nst;
    118     int qsz = SZ(Q[qid]);
    119     
    120     while (qsz--) {
    121         cst = Q[qid].front();
    122         Q[qid].pop();
    123         
    124         int step = visit[qid][0][0][cst] + 1;
    125         rep(i, 0, sz[cst]) {
    126             nst = Move[cst][i];
    127             if (visit[qid][0][0][nst] == -1) {
    128                 if (visit[qid^1][0][0][nst] >= 0)
    129                     return step + visit[qid^1][0][0][nst];
    130                 visit[qid][0][0][nst] = step;
    131                 Q[qid].push(nst);
    132             }
    133         }
    134     }
    135     
    136     return -1;
    137 }
    138 
    139 int bfs2(const int qid) {
    140     int cst[2], nst[2], tmp;
    141     int qsz = SZ(Q[qid]);
    142     
    143     while (qsz--) {
    144         st = Q[qid].front();
    145         Q[qid].pop();
    146         
    147         per(i, 0, 2) {
    148             cst[i] = st & 0xff;
    149             st >>= 8;
    150         }
    151         
    152         int step = visit[qid][0][cst[0]][cst[1]] + 1;
    153         
    154         rep(i, 0, sz[cst[0]]) {
    155             nst[0] = Move[cst[0]][i];
    156             rep(j, 0, sz[cst[1]]) {
    157                 nst[1] = Move[cst[1]][j];
    158                 if (nst[0]==nst[1] || (nst[0]==cst[1]&&nst[1]==cst[0]))
    159                     continue;
    160                 
    161                 tmp = nst[0]<<8 | nst[1];
    162                 if (visit[qid][0][nst[0]][nst[1]] == -1) {
    163                     if (visit[qid^1][0][nst[0]][nst[1]] != -1)
    164                         return step + visit[qid^1][0][nst[0]][nst[1]];
    165                     visit[qid][0][nst[0]][nst[1]] = step;
    166                     Q[qid].push(tmp);
    167                 }
    168             }
    169         }
    170     }
    171     
    172     return -1;
    173 }
    174 
    175 inline bool check(int *nst, int *cst) {
    176     return (nst[0]==cst[1] && nst[1]==cst[0]) || (nst[0]==cst[2] && nst[2]==cst[0]) || (nst[1]==cst[2] && nst[2]==cst[1]);
    177 }
    178 
    179 int bfs3(const int qid) {
    180     int cst[3], nst[3], tmp;
    181     int qsz = SZ(Q[qid]);
    182     
    183     while (qsz--) {
    184         st = Q[qid].front();
    185         Q[qid].pop();
    186         
    187         per(i, 0, 3) {
    188             cst[i] = st & 0xff;
    189             st >>= 8;
    190         }
    191         
    192         int step = visit[qid][cst[0]][cst[1]][cst[2]] + 1;
    193         
    194         rep(i, 0, sz[cst[0]]) {
    195             nst[0] = Move[cst[0]][i];
    196             rep(j, 0, sz[cst[1]]) {
    197                 nst[1] = Move[cst[1]][j];
    198                 rep(k, 0, sz[cst[2]]) {
    199                     nst[2] = Move[cst[2]][k];
    200                     if (nst[0]==nst[1] || nst[1]==nst[2] || nst[0]==nst[2] || check(cst, nst))
    201                         continue;
    202                     
    203                     tmp = (nst[0]<<16) | (nst[1]<<8) | (nst[2]);
    204                     
    205                     if (visit[qid][nst[0]][nst[1]][nst[2]] == -1) {
    206                         if (visit[qid^1][nst[0]][nst[1]][nst[2]] != -1)
    207                             return step + visit[qid^1][nst[0]][nst[1]][nst[2]];
    208                         visit[qid][nst[0]][nst[1]][nst[2]] = step;
    209                         Q[qid].push(tmp);
    210                     }
    211                 }
    212             }
    213         }
    214     }
    215     
    216     return -1;
    217 }
    218 
    219 #define bibfs(n)
    220 int bibfs##n() {
    221     int tmp;    
    222                 
    223     while (!Q[0].empty() || !Q[1].empty()) {
    224         tmp = bfs##n(0);
    225         if (tmp >= 0)    return tmp;
    226         tmp = bfs##n(1);
    227         if (tmp >= 0)    return tmp;
    228     }
    229                 
    230     return -1;
    231 }
    232 
    233 #define callbibfs(n) bibfs##n()
    234 
    235 bibfs(1)
    236 bibfs(2)
    237 bibfs(3)
    238 
    239 void solve() {
    240     init();
    241     int ans;
    242     
    243     memset(visit, -1, sizeof(visit));
    244     rep(i, 0, 2)
    245         while (!Q[i].empty()) Q[i].pop();
    246     visit[0][st>>16][(st>>8)&0xff][st&0xff] = 0;
    247     visit[1][ed>>16][(ed>>8)&0xff][ed&0xff] = 0;
    248     Q[0].push(st);
    249     Q[1].push(ed);
    250     
    251     if (gn == 1) {
    252         ans = callbibfs(1);
    253     } else if (gn == 2) {
    254         ans = callbibfs(2);
    255     } else {
    256         ans = callbibfs(3);
    257     }
    258     
    259     printf("%d
    ", ans);
    260 }
    261 
    262 int main() {
    263     ios::sync_with_stdio(false);
    264     #ifndef ONLINE_JUDGE
    265         freopen("data.in", "r", stdin);
    266         freopen("data.out", "w", stdout);
    267     #endif
    268     
    269     while (scanf("%d%d%d%*c",&m,&n,&gn)!=EOF && (n||m||gn)) {
    270         rep(i, 0, n)
    271             gets(s[i]);
    272         solve();
    273     }
    274     
    275     #ifndef ONLINE_JUDGE
    276         printf("time = %d.
    ", (int)clock());
    277     #endif
    278     
    279     return 0;
    280 }
  • 相关阅读:
    《MySQL技术内幕》读书笔记
    CentOS裸机环境下安装php-7.3.1
    docker容器和本机互传文件
    一些数组操作函数记录
    window下强制删除文件
    根据一个镜像启动一个容器
    Nginx配置命令大全
    《Linux.Shell编程从入门到精通》读书笔记
    share drive 无效
    vi替换字符串
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5313627.html
Copyright © 2011-2022 走看看