拯救公主
时间限制: 1 Sec 内存限制: 128 MB[ 提交][ 状态][ 讨论版]
题目描述
公主被妖怪抓到了一个山洞里,为了尽快营救公主,王子决定不回城搬救兵去独自营救。山洞为矩形且十分空旷,其中生活着K个妖怪。幸运的是这些妖怪晚上都会睡觉并且没人守夜。但是若是离妖怪太近就会惊醒它,其他的妖怪也会被惊醒,所以我们要找一条距离所有妖怪都很远的路。我们把山洞分为了n*m个格子,走到相邻的格子(不含对角)王子需要一步,妖怪只占一个格子的大小。王子希望你给他一条尽可能安全的路,你只需要告诉他,这条路上离妖怪最近的时候距离是多少(最少走K步可到则认为最近距离为k)。入口在1行1列,公主在n行m列。
输入
n,m,k(地图为n行*m列,k为妖怪个数)(1<n,m<=1000,1<k<=100)
之后有k行每行两个数xi,yi(表示妖怪在xi行,yi列)
之后有k行每行两个数xi,yi(表示妖怪在xi行,yi列)
输出
离妖怪最近的距离
样例输入
3 3 2
1 3
3 1
样例输出
1
提示
离妖怪最近的距离
注意:走到哪个位置就计算到每个妖怪的距离,并取最小值,取这条路径上的最小值的最大距离并输出结果
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
#include<cstdio>
using namespace std;
#define MIN(x,y) (x<y?x:y)
#define INF 0x3f3f3f3f
const int c[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int Map[1003][1003],vis[1003][1003],vis2[1003][1003];
int n,m,k,a[1003],b[1003],dp[1003][1003];
struct node{
int x,y;
int v;
friend bool operator < (const node &aa,const node &bb){
return aa.v<bb.v;
}
};
bool check(int i,int j)
{
if(i>=1 && i<=n && j>=1 && j<=m && Map[i][j]) return true;
else return false;
}
int huan(int s,int d)
{
if (dp[s][d]) return dp[s][d];
int t,dd=INF;
for(int i=1;i<=k;i++){
t=abs(a[i]-s)+abs(b[i]-d);
if(t<dd) dd=t;
}
dp[s][d]=dd;
return dd;
}
int bfs(int xx,int yy)
{
int dd=0;
priority_queue<node> q,p;
node now,tmp,now2,tmp2;
now.x=xx; now.y=yy; now.v=huan(xx,yy);
now2.x=n; now2.y=m; now2.v=huan(n,m);
q.push(now); p.push(now2);
vis[now.x][now.y]=1;
vis2[now2.x][now2.y]=1;
while(!q.empty() && !p.empty()){
now=q.top(); q.pop();
now2=p.top(); p.pop();
if(vis2[now.x][now.y]){
dd=1;
break;
}
if(vis[now2.x][now2.y]){
dd=2;
break;
}
for(int i=0;i<4;i++){
tmp.x=now.x+c[i][0];
tmp.y=now.y+c[i][1];
tmp.v=min(huan(tmp.x,tmp.y),now.v);
if(check(tmp.x,tmp.y) && !vis[tmp.x][tmp.y]){
q.push(tmp);
vis[tmp.x][tmp.y]=1;
}
tmp2.x=now2.x+c[i][0];
tmp2.y=now2.y+c[i][1];
tmp2.v=min(huan(tmp2.x,tmp2.y),now2.v);
if(check(tmp2.x,tmp2.y) && !vis2[tmp2.x][tmp2.y]){
p.push(tmp2);
vis2[tmp2.x][tmp2.y]=1;
}
}
}
if(dd==1){
int w=MIN(now.v,now2.v);
return w;
}
else if(dd==2){
int s=MIN(now.v,now2.v);
return s;
}
else return 0;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k)){
memset(Map,INF,sizeof(Map));
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=1;i<=k;i++){
scanf("%d%d",&a[i],&b[i]);
Map[a[i]][b[i]]=0;
}
printf("%d\n",bfs(1,1));
}
return 0;
}
运行时间为 : 420 ms
多给几组测试数据:
(1):1000 1000 10
161 203
85 591
494 633
563 935
517 722
595 363
989 174
448 825
902 939
430 386
输出为:98
(2)1000 1000 10
732 474
449 988
119 239
306 233
258 268
627 992
225 792
237 601
72 361
1 951
输出为:232