時間限制:1 秒
內存限制:32 兆
特殊判題:否
提交:285
解決:55
- 題目描述:
-
ID爲TMao的淘寶用戶前些日子在淘寶機器人網店購買了一個智能機器人oz.這個機器人不僅精緻小巧,還具有很多有意思的功能。
比如:oz可以在迷宮裏自由的上下左右走動; 並且,在不碰到障礙物的情況下,它能夠以最短時間從入口處走到出口 (假設存在的話); 最智能的是,在有充電器的地方oz還可以給自己充電 (^_^)。
現在,TMao設計了很多種迷宮,並且在裏面隨意的擺了些充電器,想請你們幫他算下,這個智能機器人要多久時間可以走出去呢?
他做了如下假設:
1.迷宮可以看作是長爲w,寬爲h的網格;
2.機器人每移動一步,需要時間1s,消耗電量0.5格;
3.機器人初始電量爲滿格4格;
4.每個充電器充電次數不限 (充電時間所需時間忽略不計),機器人可以反覆經過一個地方,但是不能走到有障礙的地方,並且一旦機器人電量變爲0,它就只能停下來,哪怕這個位置正好有充電器,它也沒有足夠的電量去執行充電操作;
5.機器人走到迷宮出口,必須至少還有0.5格電量,否則也算沒走出出口。
- 輸入:
-
輸入有多組測試案例,每個測試案例以如下形式輸入。
第一行輸入w,h分別表示迷宮的長和寬,當輸入0 0時結束輸入(w , h <= 10)。
接下來的h行表示迷宮的佈局:-1表示該位置是障礙物, 0表示該位置什麼也沒有,1表示迷宮入口, 2表示迷宮出口, 3表示該位置有充電器。
- 輸出:
-
對應每個測試案例,輸出機器人oz走到出口處的時間;如果無法按要求走到出口則輸出”Pity oz!”。
- 樣例輸入:
-
4 3
2 0 0 0
0 0 0 0
0 0 0 1
4 3
2 -1 0 0
-1 0 0 0
3 0 0 1
0 0
- 樣例輸出:
-
5
Pity oz!
這道題是最短路徑問題,不過他加了一些限制條件。
就是每次到了一個新的充電地方就可以以飽滿的電量繼續前進。
所以我就先從起點開始找。
每次到了一個充電點且比以前的路勁更優的話就可以更新路徑。
再把這個點繼續入隊列,下一次又從這一個點開始BFS搜索。
直到全部搜索完畢。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
int map[13][13];
int minpath[13][13]; //用來存放從原點到這一步i,j的最小步數。
int row,col;
int endi,endj;
int dir[][2] = {{-1,0},{0,-1},{1,0},{0,1}};
struct node
{
int x,y;
int pu; //真正的步數
int p; //電池的數字用1~7表示
bool operator < (const node& a)const
{
return pu>a.pu;
}
};
priority_queue<node> pq;
int Min(int a,int b)
{
return a>b?b:a;
}
void BFS(struct node no)
{
queue <node> q;
q.push(no);
struct node var;
while(!q.empty())
{
no = q.front();
q.pop();
if(map[no.x][no.y]==2)
minpath[no.x][no.y] = Min(minpath[no.x][no.y],no.pu);
if(map[no.x][no.y]==3 && no.pu<minpath[no.x][no.y])//每次找到充電點還要判斷他是否是比上一次更優
{
minpath[no.x][no.y] = no.pu;
var = no;
var.p = 0; //每次找到一個充電點就把充電歸零
pq.push(var); //每次找到一個充電點就要把它入隊列。。核心核心
}
for(int i=0;i<4;i++)
{
int x = no.x+dir[i][0];
int y = no.y+dir[i][1];
if(map[x][y]!=-1 && no.p<7) //不能到7,到7就是隻有0.5電量,不能進行下一步了
{
var.x = x;
var.y = y;
var.pu = no.pu+1;
var.p = no.p+1;
q.push(var);
}
}
}
}
int main()
{
int i,j;
while(scanf("%d%d",&col,&row) && row+col!=0)
{
struct node no;
memset(map,-1,sizeof(map));
memset(minpath,0x3f,sizeof(minpath));
while(!pq.empty())
pq.pop();
for(i=1;i<=row;i++)
for(j=1;j<=col;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==1)
{
no.x = i;
no.y = j;
no.p = no.pu = 0;
pq.push(no);
}
if(map[i][j]==2)
{
endi = i;
endj = j;
}
}
while(!pq.empty())
{
no = pq.top();
pq.pop();
BFS(no);
}
if(minpath[endi][endj]!=minpath[0][0]) //minpath[0][0]一直沒有變化,所以和它比
printf("%d\n",minpath[endi][endj]);
else
printf("Pity oz!\n");
}
return 0;
}