拯救公主

来源:互联网 发布:枪械原理的软件 编辑:程序博客网 时间:2024/07/24 02:39
时间限制: 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<=n*m)
之后有k行每行两个数xi,yi(表示妖怪在xi行,yi列)

输出

离妖怪最近的距离

样例输入

3 3 21 33 1

样例输出

1

提示


k值变大



最近距离的算法为行数差加列数差(即从入口到公主的最短距离为(n-1)+(m-1)


//双向优先队列+dp #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>using namespace std;const int INF=9999999;struct node{int x,y,s;bool operator < (const node &a) const{  return a.s>s;} };int n,m,k,mm,mmm,flag,sum,pd1[1110][1110],pd2[1110][1110],z[1110][1110],dp[1110][1110];int e[1110][1110],b[1110],s[1110],map3[1110][1110],map[1110][1110],map1[1110][1110],map2[1110][1110];int c[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int min(int a,int b){return a<b?a:b;} int insert(int b,int c){if(b<1 || b>n || c<1 || c>m || e[b][c]) return false;return true;}int bfs(int x1,int y1){struct node t1,t2,t3,tp1,tp2,tp3;priority_queue<node> q1,q2;t1.x=x1;t1.y=y1;t1.s=map3[t1.x][t1.y];q1.push(t1);pd1[t1.x][t1.y]=1;tp1.x=n;tp1.y=m;tp1.s=map3[tp1.x][tp1.y];q2.push(tp1);pd2[tp1.x][tp1.y]=2;while(!q1.empty() && !q2.empty()){t2=q1.top();q1.pop();tp2=q2.top();q2.pop();if(pd1[tp2.x][tp2.y]){flag=1;int u=min(t2.s,tp2.s);return u;}if(pd2[t2.x][t2.y]){flag=1;int uu=min(t2.s,tp2.s);return uu;}    for(int i=0;i<4;i++){    t3.x=t2.x+c[i][0];    t3.y=t2.y+c[i][1];    int q=min(map3[t3.x][t3.y],t2.s);    t3.s=q;    if(insert(t3.x,t3.y) && !pd1[t3.x][t3.y]){    q1.push(t3);    pd1[t3.x][t3.y]=1;    }            tp3.x=tp2.x+c[i][0];    tp3.y=tp2.y+c[i][1];    int qq=min(map3[tp3.x][tp3.y],tp2.s);    tp3.s=qq;    if(insert(tp3.x,tp3.y) && !pd2[tp3.x][tp3.y]){    q2.push(tp3);    pd2[tp3.x][tp3.y]=1;    }    }}return 0;}int main(){           int x,y,mid;while(scanf("%d%d%d",&n,&m,&k)!=EOF){    flag=0;mid=0;memset(e,0,sizeof(e));memset(z,0,sizeof(z));memset(b,0,sizeof(b));memset(s,0,sizeof(s));memset(pd1,0,sizeof(pd1));memset(pd2,0,sizeof(pd2));memset(map,INF,sizeof(map));memset(map1,INF,sizeof(map1));memset(map2,INF,sizeof(map2));memset(map3,0,sizeof(map3));for(int i=0;i<k;i++){   scanf("%d%d",&x,&y);   e[x][y]=1;   b[i]=x;   s[i]=y;   map[x][y]=0;   for(int j=1;j<=m;j++){   map[x][j]=min(abs(y-j),map[x][j]);   }}for(int j=1;j<=m;j++){map1[1][j]=map[1][j];for(int i=2;i<=n;i++){if(map[i][j]>map1[i-1][j]+1)map1[i][j]=map1[i-1][j]+1;else    map1[i][j]=map[i][j];}map2[n][j]=map[n][j];   for(int i=n-1;i>=1;i--){if(map[i][j]>map2[i+1][j]+1)  map2[i][j]=map2[i+1][j]+1;else  map2[i][j]=map[i][j];}}  for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ map3[i][j]=min(map1[i][j],map2[i][j]); } }    int sum=bfs(1,1);   if(flag)       printf("%d\n",sum);       else       printf("0\n");}  return 0;} //单向广度优先搜索 #include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<cstring>using namespace std;struct node{int x,y,s;bool operator < (const node &a) const{  return a.s>s;} };int n,m,k,mm;int e[1110][1110],b[1110],s[1110],dp[1110][1110];int c[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int cmp(int xx,int yy){if(dp[xx][yy]) return dp[xx][yy];int mixn=9999999;for(int i=0;i<k;i++){int ss=abs(xx-b[i])+abs(yy-s[i]);if(ss<mixn) mixn=ss;}dp[xx][yy]=mixn;return mixn;}int bfs(int x1,int y1){struct node t1,t2,t3;priority_queue<node> q;int qq=cmp(x1,y1);t1.x=x1;t1.y=y1;t1.s=qq;q.push(t1);while(!q.empty()){t2=q.top();q.pop();if(mm>t2.s)   mm=t2.s;for(int i=0;i<4;i++){t3.x=t2.x+c[i][0];t3.y=t2.y+c[i][1];int kk=cmp(t3.x,t3.y);t3.s=kk;if(t3.x<1 || t3.x>n || t3.y<1 || t3.y>m || e[t3.x][t3.y]==1)continue;if(t3.x==n && t3.y==m){return mm;} q.push(t3);e[t3.x][t3.y]=1;    }}return 0; }int main(){ int x,y;while(scanf("%d%d%d",&n,&m,&k)!=EOF){mm=9999999;memset(b,0,sizeof(b));memset(s,0,sizeof(s));memset(e,0,sizeof(e));memset(dp,0,sizeof(dp));   for(int i=0;i<k;i++){     scanf("%d%d",&x,&y);     e[x][y]=1;     b[i]=x;     s[i]=y;   }   int flag=bfs(1,1);   if(flag)       printf("%d\n",flag);       else       printf("0\n");}  return 0;} //广度双向优先搜索#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>using namespace std;struct node{int x,y,s;bool operator < (const node &a) const{  return a.s>s;} };int n,m,k,mm,mmm,flag,sum,pd1[1110][1110],pd2[1110][1110],z[1110][1110],dp[1110][1110];int e[1110][1110],b[1110],s[1110];int c[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int min(int a,int b){return a<b?a:b;}int cmp(int xx,int yy){if(dp[xx][yy]) return dp[xx][yy];int mixn=9999999;for(int i=0;i<k;i++){int ss=abs(xx-b[i])+abs(yy-s[i]);if(ss<mixn)mixn=ss;}dp[xx][yy]=mixn;return mixn;}int insert(int b,int c){if(b<1 || b>n || c<1 || c>m || e[b][c]) return false;return true;}int bfs(int x1,int y1){struct node t1,t2,t3,tp1,tp2,tp3;priority_queue<node> q1,q2;t1.x=x1;t1.y=y1;t1.s=cmp(x1,y1);q1.push(t1);pd1[t1.x][t1.y]=1;tp1.x=n;tp1.y=m;tp1.s=cmp(n,m);q2.push(tp1);pd2[tp1.x][tp1.y]=2;while(!q1.empty() && !q2.empty()){t2=q1.top();q1.pop();tp2=q2.top();q2.pop();if(pd1[tp2.x][tp2.y]){flag=1;int u=min(t2.s,tp2.s);return u;}if(pd2[t2.x][t2.y]){flag=1;int uu=min(t2.s,tp2.s);return uu;}    for(int i=0;i<4;i++){    t3.x=t2.x+c[i][0];    t3.y=t2.y+c[i][1];    int q=min(cmp(t3.x,t3.y),t2.s);    t3.s=q;    if(insert(t3.x,t3.y) && !pd1[t3.x][t3.y]){    q1.push(t3);    pd1[t3.x][t3.y]=1;    }            tp3.x=tp2.x+c[i][0];    tp3.y=tp2.y+c[i][1];    int qq=min(cmp(tp3.x,tp3.y),tp2.s);    tp3.s=qq;    if(insert(tp3.x,tp3.y) && !pd2[tp3.x][tp3.y]){    q2.push(tp3);    pd2[tp3.x][tp3.y]=1;    }    }}return 0;}int main(){int x,y;while(scanf("%d%d%d",&n,&m,&k)!=EOF){mm=9999999;mmm=9999999;flag=0;sum=0;memset(b,0,sizeof(b));memset(s,0,sizeof(s));memset(e,0,sizeof(e));memset(pd1,0,sizeof(pd1));memset(pd2,0,sizeof(pd2));memset(z,0,sizeof(z));memset(dp,0,sizeof(dp));   for(int i=0;i<k;i++){     scanf("%d%d",&x,&y);     e[x][y]=1;     b[i]=x;     s[i]=y;   }   int sum=bfs(1,1);   if(flag)       printf("%d\n",sum);       else       printf("0\n");}  return 0;} //bfs+二分 #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>using namespace std;struct node{int x,y,s;};int n,m,k,flag,sum,dp[1110][1110],vis[1110][1110],z[1110];int e[1110][1110],b[1110],s[1110];int c[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int cmp(int xx,int yy){if(dp[xx][yy]) return dp[xx][yy];int mixn=9999999;for(int i=0;i<k;i++){int ss=abs(xx-b[i])+abs(yy-s[i]);if(ss<mixn)mixn=ss;}dp[xx][yy]=mixn;return mixn;}int insert(int b,int c){if(b<1 || b>n || c<1 || c>m || e[b][c]) return false;return true;}int cmp1(int xx,int yy){int maxn=0;for(int i=0;i<k;i++){int ss=abs(xx-b[i])+abs(yy-s[i]);if(ss>maxn)maxn=ss;}return maxn;}int bfs(int r){memset(vis,0,sizeof(vis));struct node t1,t2,t3;queue<node> q;t1.x=1;t1.y=1;t1.s=cmp(t1.x,t1.y);vis[t1.x][t1.y]=1;    q.push(t1);while(!q.empty()){t2=q.front();q.pop();for(int i=0;i<4;i++){t3.x=t2.x+c[i][0];t3.y=t2.y+c[i][1];int rr=cmp(t3.x,t3.y);if(insert(t3.x,t3.y) && vis[t3.x][t3.y]==0 && rr>=r){if(t3.x==n && t3.y==m){       return 1;        }q.push(t3);vis[t3.x][t3.y]=1;}}}return 0;}int main(){int x,y,mid;while(scanf("%d%d%d",&n,&m,&k)!=EOF){    flag=0;mid=0;memset(b,0,sizeof(b));memset(s,0,sizeof(s));memset(e,0,sizeof(e));memset(dp,0,sizeof(dp));memset(z,0,sizeof(z));memset(vis,0,sizeof(vis));for(int i=0;i<k;i++){   scanf("%d%d",&x,&y);   e[x][y]=1;   b[i]=x;   s[i]=y;}int kk=cmp1(1,1),left=0;    while(left<=kk){    mid=(left+kk)/2;    if(bfs(mid)){    flag=1;    left=mid+1;    }       else{    flag=2;    kk=mid-1;    }    }    if(flag==1)cout << mid << endl;else if(flag==2){   if(mid==0) cout << "0" << endl;       else cout << mid-1 << endl;    }}return 0;}  

 

0 0
原创粉丝点击