Superbot
题目链接:ZOJ - 3865题意:一个N*M地图, 可以通过光标移动机器人, 使之找到钻石(@表示机器人初始位置, $表示钻石位置, *表示障碍, .表示空地),每p秒光标自动右移, 每秒一个操作,四个操作:
1> 按光标移动
2> 光标左移
3> 光标右移
4> 不动
初始时光标位置是 left , right , up , down;
光标的移动如下图:

每次移动有三个状态, 坐标 x, y, 光标位置 z;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int dir[4][2]={0, -1, 0, 1, -1, 0, 1, 0};
int n, m, p, sx, sy, ex, ey;
char maze[15][15];
bool vis[15][15][5];
bool ok(int x, int y){
if(x<0||x>=n||y<0||y>=m) return false;
if(maze[x][y]=='*') return false;
return true;
}
struct node{
int x, y;
int t;
int z;//光标位置
node(){};
node(int xx, int yy, int tt, int zz){
x=xx;
y=yy;
t=tt;
z=zz;
}
};
queue<node> que;
int bfs(){
while(!que.empty()) que.pop();
node tmp=node(sx, sy, 0, 0);
que.push(tmp);
memset(vis, false, sizeof(vis));
vis[sx][sy][0]=true;
while(!que.empty()){
tmp=que.front();
que.pop();
// cout<<"x: "<<tmp.x<<" , y: "<<tmp.y<<endl;
// cout<<"cmd: "<<tmp.z<<" time "<<tmp.t<<endl;
// cout << "-----------------\n";
if(tmp.x==ex&&tmp.y==ey||maze[tmp.x][tmp.y]=='$'){
return tmp.t;
}
//光标左移
node v=tmp;
v.z=(v.z+1)%4;
v.t++;
if(v.t%p==0) v.z=(v.z+4-1)%4;
if(!vis[v.x][v.y][v.z]){
vis[v.x][v.y][v.z]=true;
que.push(v);
}
//光标右移
v=tmp;
v.z=(v.z+4-1)%4;
v.t++;
if(v.t%p==0) v.z=(v.z+4-1)%4;
if(!vis[v.x][v.y][v.z]){
vis[v.x][v.y][v.z]=true;
que.push(v);
}
//不动
v=tmp;
v.t++;
if(v.t%p==0) v.z=(v.z+4-1)%4;
if(!vis[v.x][v.y][v.z]){
vis[v.x][v.y][v.z]=true;
que.push(v);
}
//移动
v=tmp;
v.x=v.x+dir[v.z][0], v.y=v.y+dir[v.z][1];
v.t++;
if(v.t%p==0) v.z=(v.z+4-1)%4;
if(!vis[v.x][v.y][v.z]&&ok(v.x, v.y)){
vis[v.x][v.y][v.z]=true;
que.push(v);
}
}
return -1;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &n, &m, &p);
for(int i=0; i<n; i++){
scanf("%s", maze[i]);
for(int j=0; j<m; j++){
if(maze[i][j]=='@') sx=i, sy=j;
if(maze[i][j]=='$') ex=i, ey=j;
}
}
int ans=bfs();
if(ans==-1) printf("YouBadbad\n");
else printf("%d\n", ans);
}
return 0;
}