题目大意:
就是在60*60的地图上现在又200只小怪兽, 每只小怪兽都是在一个长度不超过7的路线上来回走, 现在要从起点到终点, 路途中和小怪兽在同一排或者同一列中且没有建筑物遮挡, 也就是说每只小怪兽都会影响到上下左右能之间看见的地方, 除了到达终点的同时是能被看见的 情况外, 其他时刻都不能被看见
移动方式为上下左右或者原地不动, 问起点到终点需要的最短时间, 不能到达就impossible
大致思路:
这种题多半考虑暴搜, 现在为了表示状态, 不能存下200只怪兽的状态, 于是考虑到走的路线长度不超过7, 那么每只怪兽的周期是1, 2, 4, 6, 8, 10, 12, 也就是说最小公共周期是240
那么用vis[x][y][t]表示状态就可以了, 表示在周期t时刻在位置x, y的到达状态即可, 状态总数 60*60*240显然是可以接受的
代码如下:
Result : Accepted Memory : 6960 KB Time : 31 ms
/* * Author: Gatevin * Created Time: 2015/12/6 14:35:58 * File Name: Yukinoshita_Yukino.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; int X, Y; int sx, sy, ex, ey; char maz[70][70]; int P; vector<pair<int, int> > V[210]; bool vis[70][70][240]; bool obunai[70][70][240];//在周期时刻t, 位置x, y是否危险表示obunai[x][y][t] int step[70][70][240]; int period[210]; //只有1, 2, 3, 4, 5, 6, 7这几种周期, 那么在LCM(1, 2, 4, 6, 8, 10, 12) = 240范围内是一个怪兽所在位置的周期 #define mp make_pair #define pb push_back int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, -1, 1}; void init() { for(int t = 0; t < 240; t++) for(int j = 0; j < P; j++) { int x = V[j][t % period[j]].first; int y = V[j][t % period[j]].second; for(int k = 0; k < 4; k++) { int tx = x, ty = y; while(tx >= 0 && tx < X && ty >= 0 && ty < Y) { if(maz[tx][ty] == '#') break; obunai[tx][ty][t] = 1; tx += dx[k], ty += dy[k]; } } } return; } queue<pair<pair<int, int>, int> > Q; void bfs() { Q.push(mp(mp(sx, sy), 0)); vis[sx][sy][0] = 1; step[sx][sy][0] = 0; while(!Q.empty()) { int nx = Q.front().first.first, ny = Q.front().first.second; int nt = Q.front().second; Q.pop(); if(obunai[nx][ny][nt]) continue; for(int i = 0; i < 4; i++) { int tx = nx + dx[i]; int ty = ny + dy[i]; int tt = (nt + 1) % 240; if(tx < 0 || tx >= X || ty < 0 || ty >= Y || maz[tx][ty] == '#') continue; if(!vis[tx][ty][tt]) { Q.push(mp(mp(tx, ty), tt)); step[tx][ty][tt] = step[nx][ny][nt] + 1; vis[tx][ty][tt] = 1; } } int tx = nx; int ty = ny; int tt = (nt + 1) % 240; if(!vis[tx][ty][tt]) { Q.push(mp(mp(tx, ty), tt)); vis[tx][ty][tt] = 1; step[tx][ty][tt] = step[nx][ny][nt] + 1; } } int ans = 1e9; for(int t = 0; t < 240; t++) if(vis[ex][ey][t]) ans = min(ans, step[ex][ey][t]); if(ans != 1e9) printf("%d\n", ans); else puts("IMPOSSIBLE"); return; } int main() { scanf("%d %d", &X, &Y); scanf("\n(%d %d) (%d %d)", &sx, &sy, &ex, &ey); sx--; sy--; ex--; ey--; for(int i = 0; i < X; i++) scanf("%s", maz[i]); scanf("%d", &P); for(int i = 0; i < P; i++) { scanf("%d", &period[i]); for(int j = 0; j < period[i]; j++) { int x, y; scanf(" (%d %d)", &x, &y); x--, y--; V[i].pb(mp(x, y)); } for(int j = period[i] - 2; j > 0; j--) V[i].pb(V[i][j]); if(period[i] >= 2) period[i] = 2*(period[i] - 2) + 2; else period[i] = 1; } init(); bfs(); return 0; } /* 5 5 (2 5) (5 3) ..... .#.#. .#.#. ....# .#.## 1 6 (4 2) (4 3) (3 3) (2 3) (1 3) (1 2) */