题目:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5477题意:
机器人在地图中找钻石的游戏,给出一个地图,' * ' 表示墙,@表示起点,$表示钻石,移动方向取决于当前光标在哪个移动按钮上。
每秒可以左右移动一下光标位置或者按当前光标移动一下机器人或者什么都不做。
同时按钮在旋转,每len秒4个按钮向右旋转一格。
求到达钻石位置所需最小时间。
思路:
只有10*10的地图,直接枚举所有方式搜索。
用BFS,在结构体中保存每种操作的所有信息:位置,当前时间,光标位置,停留时间。
之后对于队列中取出的每种情况都可以分成最多4中情况:
按当前光标位置移动机器人,向左移动光标,向右移动光标,什么都不做(等旋转)。
注意在不移动的情况下要更新停留时间,防止死循环,每个位置最多停留2秒。
在判断移动机器人时,加入当前时间计算按钮旋转次数,确定当前移动方向是否可移动。
代码:
#define N 112
int n,m;
int x,y,xx,yy;
int flag,sum,ave,ans,res,len;
int g[N][N];
int dir[4][2]={0,-1,0,1,-1,0,1,0};
bool vis[N][N];
char s[101];
struct node
{
int x,y;
int r,w;
int num;
}tn;
void init()
{
memset(vis,false,sizeof(vis));
memset(g,0,sizeof(g));
}
void solve()
{
int i,j,k,tx,ty;
sum=1;
queue<node> q;
while(!q.empty())q.pop();
node h,p;
h.x=x;h.y=y;
h.r=0;h.w=0;
h.num=0;
q.push(h);
while(!q.empty())
{
h=q.front();q.pop();
vis[h.x][h.y]=true;
//计算移动位置
x=h.x+dir[(1000*4-h.w/len+h.r)%4][0];
y=h.y+dir[(1000*4-h.w/len+h.r)%4][1];
if(x==xx&&y==yy)
{
printf("%d\n",h.w+1);
return;
}
//移动机器人
if(g[x][y]&&!vis[x][y])
{
p.x=x;p.y=y;
p.r=h.r;
p.w=h.w+1;
p.num=0;
q.push(p);
vis[x][y]=true;
}
if(h.num<2)
{
p.x=h.x;p.y=h.y;
p.w=h.w+1;
p.num=h.num+1;
//右移光标
p.r=h.r+1;
p.r%=4;
q.push(p);
//左移光标
p.r=h.r+4-1;
p.r%=4;
q.push(p);
//什么都不做
p.r=h.r;
q.push(p);
}
}
printf("YouBadbad\n");
}
int main()
{
int i,j,k,kk,t,z;
scanf("%d",&k);
while(k--)
{
init();
scanf("%d%d%d",&n,&m,&len);
for(i=1;i<=n;i++)
{
scanf("%s",s);
for(j=1;j<=m;j++)
{
if(s[j-1]=='.')
g[i][j]=1;
else if(s[j-1]=='*')
g[i][j]=0;
else if(s[j-1]=='@')
g[i][j]=0,x=i,y=j;
else
g[i][j]=1,xx=i,yy=j;
}
}
solve();
}
return 0;
}