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; }