题目大意:
就是在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)
*/