Codeforces Round #442 (Div. 2)-广搜&剪枝&技巧&好题-D. Olya and Energy Drinks
来源:互联网 发布:英雄皮肤淘宝店 编辑:程序博客网 时间:2024/05/17 22:51
http://codeforces.com/contest/877/problem/D
给定一个点,问你从x点到y点,需要的最少时间。
没秒可以走小于等于k步。
暴力的bfs也是没谁了。。怎么可能过。
后来又写了一种方案,枚举每个点往前后左右的最大可移动距离,还是t
(再51nod见过一道类似这种方法的。)
百度之,好多方法。
① 剪枝,相同方向剪,维护局部最小距离剪。
② 把vis变量分为四个方向,然后根据方向剪。
(即对于某一个点。如果相同方向再次使来,肯定不是最短距离了,这个剪枝也不错。)
③ 并查集,并查集大佬qwq
我郁闷了,bfs本来就能在最短的达到,我还维护,根本不用维护,一旦到达那么久肯定是最优解的了qwq
#include <bits/stdc++.h>using namespace std;/*这个代码有个细节,我交了几十遍才发现,那就是,当有另一个方向到达的该点,和曾经该点的最小时间一样大, 那么不要剪掉。。也就是,那个 vis[x][y]<u.tim+1 ,不能取等号。。。坑死了*/const int maxn=1e3+320;int m,n,k;char a[maxn][maxn];struct Node{ int x,y,tim; Node(){}; Node(int _x,int _y,int _tim){ x=_x; y=_y; tim=_tim; };};queue<Node>q;int x1,y_1,x2,y2;int vis[maxn][maxn];int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int main(){ while(~scanf("%d%d%d",&m,&n,&k)){ for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ scanf(" %c",&a[i][j]); } } memset(vis,0x3f,sizeof(vis)); scanf("%d%d%d%d",&x1,&y_1,&x2,&y2); vis[x1][y_1]=0; q.push(Node(x1,y_1,0)); int ans=1e9; while(!q.empty()){ Node u=q.front(); q.pop(); for(int j=0;j<4;j++) { for(int i=1;i<=k;i++){ int xx=fx[j][1]*i+u.x; int yy=fx[j][0]*i+u.y; if(xx==x2&&yy==y2){ vis[xx][yy]=min(vis[xx][yy],u.tim+1); continue; } if(xx<1||xx>m||yy<1||yy>n)break; if(vis[xx][yy]<u.tim+1) break; if(a[xx][yy]=='#') break; if(vis[xx][yy]>u.tim+1){ vis[xx][yy]=u.tim+1; q.push(Node(xx,yy,u.tim+1)); } } } } ans=vis[x2][y2]; if(ans==0x3f3f3f3f) ans=-1; printf("%d\n",ans); } return 0;}
B 用方向进行剪枝。
#include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; #define mst(a,b) memset((a),(b),sizeof(a)) #define rush() int T;scanf("%d",&T);while(T--) typedef long long ll; const int maxn = 1005; const ll mod = 1e9+7; const int INF = 0x3f3f3f3f; const double eps = 1e-9; const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int n,m,k; int sx,sy,ex,ey; int vis[maxn][maxn]; char mp[maxn][maxn]; int dis[maxn][maxn]; struct node { int x,y; }now,nex; bool inbound(node a) { return a.x>=1&&a.x<=n&&a.y>=1&&a.y<=m; } void bfs() { queue<node>q; now.x=sx; now.y=sy; q.push(now); vis[sx][sy]=(1<<4)-1; //起点只经过一次就好 while(q.size()) { now=q.front(); q.pop(); if(now.x==ex&&now.y==ey) return; //搜到终点 for(int i=0;i<4;i++) //枚举方向 for(int j=1;j<=k;j++) //枚举走的步数 { nex.x=now.x+dir[i][0]*j; nex.y=now.y+dir[i][1]*j; if(!inbound(nex)||mp[nex.x][nex.y]=='#') break; //该位置不合法 if(vis[nex.x][nex.y]&(1<<i)) break; //从这个方向已经走过该位置 int flag=0; if(!vis[nex.x][nex.y]) flag=1; //搜到没有走过的点 vis[nex.x][nex.y]|=(1<<i); //更新状态 if(flag) { dis[nex.x][nex.y]=dis[now.x][now.y]+1; q.push(nex); } } } } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) { scanf("%s",mp[i]+1); } scanf("%d%d%d%d",&sx,&sy,&ex,&ey); bfs(); if(vis[ex][ey]) printf("%d\n",dis[ex][ey]); else puts("-1"); return 0; }
阅读全文
0 0
- Codeforces Round #442 (Div. 2)-广搜&剪枝&技巧&好题-D. Olya and Energy Drinks
- Codeforces Round #442 (Div. 2) D. Olya and Energy Drinks
- Codeforces Round #877 (Div. 2) D. Olya and Energy Drinks
- Codeforces Round #442(Div.2)Problem D Olya and Energy Drinks(BFS)
- Codeforces Round #442 (Div. 2) 877 D. Olya and Energy Drinks BFS
- Codeforces Round #442 (Div. 2) D. Olya and Energy Drinks (bfs)
- Codeforces Round #442 (Div. 2) Olya and Energy Drinks(搜索 bfs 套路题)
- codeforces 877 problem D Olya and Energy Drinks 【bfs剪枝】
- Codeforces 877 D Olya and Energy Drinks
- codeforces #442 div2 Olya and Energy Drinks
- Codeforces 877D Olya and Energy Drinks【思维优化Bfs】
- Codeforces 877 D. Olya and Energy Drinks (bfs)
- [codeforces] 877D. Olya and Energy Drinks (BFS)
- cf 877D Olya and Energy Drinks
- Codeforces 877D. Olya and Energy Drinks BFS+并查集
- Codeforces Codeforces Round #432 (Div. 2 D ) Arpa and a list of numbers 爆搜+剪枝
- Codeforces Round #264 (Div. 2) D. Gargari and Permutations 多序列LIS+dp好题
- Codeforces Round #395(Div. 2)D. Timofey and rectangles【思维】好题!
- 在Linux和Windows下安装SVN钩子脚本
- 聚类
- 修改div内A标签的href值
- POJ 1475 Pushing Boxes
- android监听返回按键
- Codeforces Round #442 (Div. 2)-广搜&剪枝&技巧&好题-D. Olya and Energy Drinks
- 线性表
- C# 利用函数反射、XML序列化/反序列化保存函数执行与输入参数列表
- 淘淘商城01---毕业两年,收货与展望
- 构造与析构
- 编译原理题
- linux篇之安装MySQL及远程连接
- 关于PHP获取服务器地址的方法
- Android 横竖屏切换