拯救公主
2015-11-15 17:46
501 查看
时间限制: 1 Sec 内存限制: 128 MB
[提交][状态][讨论版]
之后有k行每行两个数xi,yi(表示妖怪在xi行,yi列)
最近距离的算法为行数差加列数差(即从入口到公主的最短距离为(n-1)+(m-1)
[提交][状态][讨论版]
题目描述
公主被妖怪抓到了一个山洞里,为了尽快营救公主,王子决定不回城搬救兵去独自营救。山洞为矩形且十分空旷,其中生活着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 [j]=map [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,t 4000 p3; 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; }
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- JavaScript中数组的排序、乱序和搜索实现代码
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- mysql 模糊搜索的方法介绍
- C#搜索文字在文件及文件夹中出现位置的方法
- C#使用动态规划解决0-1背包问题实例分析