题目:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5477
题意:
给你一个n*m的地图,求出从@走到$的最小时间.使用按钮去控制人走的方向.
四个按钮的初始位置是(左,右,上,下).每p秒按钮会向右移动变成(下,左,右,上).
思路:
BFS.
vis[x][y][按钮方向][时间] 记录走过的位置.
在p秒来临前有三种: 按, 光标左移,光标右移
p秒时: 按后按钮动, 光标左移, 光标右移, 光标不动. (光标不动的情况时间要%4, 表示又回到了原来的位置.
AC.
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n, m, p;
char mp[15][15];
int r[5];
int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};
struct node {
int x, y, id, step;
node(int xx, int yy, int ii, int s) {
x = xx; y = yy; id = ii; step = s;
}
// bool operator < (const node&A) const {
// return step > A.step;
// }
};
queue<node> que;
int edx, edy, stx, sty;
bool vis[15][15][10][500];
bool ok(int tx, int ty)
{
if(tx < 0 || tx >= n || ty < 0 || ty >= m
|| mp[tx][ty] == '*') return false;
return true;
}
void rot()
{
int t = r[3];
r[3] = r[2]; r[2] = r[1]; r[1] = r[0]; r[0] = t;
}
void bfs()
{
memset(vis, 0, sizeof(vis));
int nx, ny, iid;
node no = node(stx, sty, 0, 0);
vis[stx][sty][0][0] = 1;
que.push(no);
while(que.size()) {
no = que.front(); que.pop();
if(no.x == edx && no.y == edy) {
printf("%d\n", no.step);
return;
}
int x = no.x, y = no.y, id = no.id, s = no.step;
s++;
if(s % p == 0) { //旋转
iid = (id-1+4)%4;//原位按
nx = x + dx[r[id]]; ny = y + dy[r[id]];
if(ok(nx, ny) && !vis[nx][ny][r[iid]][s]) {
no = node(nx, ny, iid, s);
vis[nx][ny][r[iid]][s] = 1;
que.push(no);
}
iid = (id-1+4)%4;//不动
if(!vis[x][y][r[iid]][s%4]) {
no = node(x, y, iid, s);
vis[x][y][r[iid]][s] = 1;
que.push(no);
}
iid = id;//右移
if(!vis[x][y][r[iid]][s]) {
no = node(x, y, iid, s);
vis[x][y][r[iid]][s] = 1;
que.push(no);
}
iid = (id-2+4)%4;//左移
if(!vis[x][y][r[iid]][s]) {
no = node(x, y, iid, s);
vis[x][y][r[iid]][s] = 1;
que.push(no);
}
}
else {//不旋转
nx = x + dx[r[id]]; ny = y + dy[r[id]];//按
if(ok(nx, ny) && !vis[nx][ny][r[id]][s] ) {
no = node(nx, ny, id, s);
vis[nx][ny][r[id]][s] = 1;
que.push(no);
}
iid = (id-1+4)%4;//左移
if(!vis[x][y][r[iid]][s]) {
no = node(x, y, iid, s);
vis[x][y][r[iid]][s] = 1;
que.push(no);
}
iid = (id+1+4)%4;//右移
if(!vis[x][y][r[iid]][s]) {
no = node(x, y, iid, s);
vis[x][y][r[iid]][s] = 1;
que.push(no);
}
}
}
printf("YouBadbad\n");
return;
}
int main()
{
//freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
for(int i = 0; i < 4; ++i) r[i] = i;
while(que.size()) que.pop();
scanf("%d %d %d", &n, &m, &p);
for(int i = 0; i < n; ++i) {
scanf("%s", mp[i]);
for(int j = 0; j < m; ++j) {
if(mp[i][j] == '$') {
edx = i; edy = j;
}
if(mp[i][j] == '@') {
stx = i; sty = j;
}
}
}
//printf("%d %d\n", edx, edy);
bfs();
}
return 0;
}