巡逻机器人
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
题意·:一个机器人从(1,1)点走到(m,n)点,中间可能有障碍,0表示路,1表示障碍。机器人一次最多可跳过k个障碍,但也相当于走了k步,问它的最小步数,如果走不到输出-1.
思路:用优先队列来存储能走的点数,步数优先,估计大多数人都会错在障碍的地方吧,因为连走的k个障碍还可以拐弯,所以就一步步地走,标记时用一个三维数组标记,其中一维是连续走了多少个障碍,如果mk[tx][ty][tf] = 1,就不要再入队了。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int mp[25][25];
int mk[25][25][30];
int m,n,k;
int nx[4][2] = {-1,0,0,-1,1,0,0,1};
struct note
{
int x,y,step,f;
note(int a,int b,int c,int d)
{
x = a;
y = b;
step = c;
f = d;
}
bool operator < (const note &a) const
{
return a.step < step;
}
};
int bfs()
{
memset(mk,0,sizeof(mk));
mk[1][1][0] = 1;
priority_queue<note> Q;
Q.push(note(1,1,0,0));
while(!Q.empty())
{
note t = Q.top();
Q.pop();
if(t.x == m && t.y == n)
return t.step;
for(int i = 0; i<4; i++)
{
int tx = t.x+nx[i][0];
int ty = t.y+nx[i][1];
int tf = t.f;
if(tx<1 || ty<1 || tx>m || ty>n)
continue;
if(mp[tx][ty] == 1)//连续走的障碍数
tf++;
else tf = 0;//初始化
if(tf<=k && mk[tx][ty][tf] == 0)
{
Q.push(note(tx,ty,t.step+1,tf));
mk[tx][ty][tf] = 1;
}
}
}
return -1;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&m,&n,&k);
for(i = 1; i<=m; i++)
for(j = 1; j<=n; j++)
scanf("%d",&mp[i][j]);
printf("%d\n",bfs());
}
return 0;
}