POJ 3278&&2049&&3083
这次的题目叫图的深度&&广度优先遍历。
然后等我做完了题发现这是DFS&&BFS爆搜专题。
3278:题目是经典的FJ,他要抓奶牛。他和牛(只有一头)在一条数轴上,他们都站在一个点上(坐标为0~1e5)。假设FJ的位置为x,他每次可以去x+1,x-1,x*2的地方。问他最少走几次才能抓到他的牛(牛不会动)。
赤裸裸的BFS,注意判断是否越界(很容易RE)
CODE
- #include<cstdio>
- #include<cstring>
- using namespace std;
- const int N=;
- int q[N*+],step[N+],n,k;
- bool vis[N+];
- inline void read(int &x)
- {
- x=; char ch=getchar();
- while (ch<''||ch>'') ch=getchar();
- while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
- }
- int main()
- {
- read(n); read(k);
- memset(vis,true,sizeof(vis));
- if (n>=k) printf("%d",n-k); else
- {
- int head=,tail=;
- q[]=n; step[n]=; vis[n]=;
- while (head<tail)
- {
- int now=q[++head];
- if (now==k) { printf("%d",step[now]); break; }
- if (now+<=N) if (vis[now+]) vis[now+]=,q[++tail]=now+,step[now+]=step[now]+;
- if (now->=) if (vis[now-]) vis[now-]=,q[++tail]=now-,step[now-]=step[now]+;
- if (now*<=N) if (vis[now*]) vis[now*]=,q[++tail]=now*,step[now*]=step[now]+;
- }
- }
- return ;
- }
2049:一道迷宫BFS,和今年NOIP PJ T3 有点类似。题意可以百度翻译(这道题翻译的还是很好的,至少能看懂)
因为他给出的是网格的边而不是点,所以要进行转化。
我们用a[x][y][0]表示(x,y)右方向的边的属性(墙或门或空地),a[x][y][1]表示(x,y)上方向的边的属性(同理)
建图玩了以后可以再连边跑SPFA或者直接松弛BFS(循环更新到每个点的的最小通过门数)
最后提醒那个人有可能不在迷宫里,就直接输出0
CODE
- #include<cstdio>
- #include<cmath>
- using namespace std;
- const int N=,INF=1e9,fx[]={,,-,},fy[]={,,,-};
- int a[N][N][],f[N][N],q[N*N*+][],n,m,i,j,x,y,d,t;
- double s_x,s_y;
- inline void read(int &x)
- {
- x=; char ch=getchar(); int flag=;
- while (ch<''||ch>'') { if (ch=='-') flag=-; ch=getchar(); }
- while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
- x*=flag;
- }
- int main()
- {
- for (;;)
- {
- read(n); read(m);
- if (n==-&&m==-) break;
- for (i=;i<N;++i)
- for (j=;j<N;++j)
- f[i][j]=INF,a[i][j][]=a[i][j][]=;
- for (i=;i<=n;++i)
- {
- read(x); read(y); read(d); read(t);
- if (d)
- {
- for (j=y;j<y+t;++j)
- a[x][j][]=;
- } else
- {
- for (j=x;j<x+t;++j)
- a[j][y][]=;
- }
- }
- for (i=;i<=m;++i)
- {
- read(x); read(y); read(d);
- if (d) a[x][y][]=; else a[x][y][]=;
- }
- scanf("%lf%lf",&s_x,&s_y);
- x=floor(s_x); y=floor(s_y);
- if (x<||y<||x>||y>||(!n&&!m)) { puts(""); continue; }
- int head=,tail=;
- q[][]=x; q[][]=y; f[x][y]=;
- while (head<tail)
- {
- x=q[++head][]; y=q[head][];
- for (i=;i<;++i)
- {
- int xx=x+fx[i],yy=y+fy[i];
- if (xx<||yy<||xx>||yy>) continue;
- if (i==)
- {
- if (a[xx][yy][]==) if (f[xx][yy]>f[x][y]) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y];
- if (a[xx][yy][]==) if (f[xx][yy]>f[x][y]+) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y]+;
- }
- if (i==)
- {
- if (a[xx][yy][]==) if (f[xx][yy]>f[x][y]) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y];
- if (a[xx][yy][]==) if (f[xx][yy]>f[x][y]+) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y]+;
- }
- if (i==)
- {
- if (a[x][y][]==) if (f[xx][yy]>f[x][y]) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y];
- if (a[x][y][]==) if (f[xx][yy]>f[x][y]+) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y]+;
- }
- if (i==)
- {
- if (a[x][y][]==) if (f[xx][yy]>f[x][y]) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y];
- if (a[x][y][]==) if (f[xx][yy]>f[x][y]+) q[++tail][]=xx,q[tail][]=yy,f[xx][yy]=f[x][y]+;
- }
- }
- }
- if (f[][]==INF) puts("-1"); else printf("%d\n",f[][]);
- }
- return ;
- }
3083:这是一道神坑题,完美的展示了爆搜的含义。
题意是一个图,S起点,E终点,.是空地,#是墙不能走。问从S到E左优先和右优先以及最短步数是多少。
DFS+BFS。BFS最短和简单,终点的DFS。
因为他要求遵循左右的性质,所以方向数组的定义就很玄学了
以左优先为例 如果现在的方向是↑,那么优先级就是←↑→↓,其他方向同理(能左转就左转,不能转就向右转再判断),右优先同理。
因此预处理一下坐标的顺序就很水了。
CODE
- #include<cstdio>
- #include<iostream>
- #include<cstring>
- using namespace std;
- const int N=,
- l[][]=
- {
- {,,,},
- {,,,},
- {,,,},
- {,,,},
- },
- r[][]=
- {
- {,,,},
- {,,,},
- {,,,},
- {,,,},
- },
- fx[]={,-,,},fy[]={-,,,};
- char a[N][N];
- int q[N*N*+][],step[N][N],i,j,n,m,s_x,s_y,e_x,e_y,t,w,l_ans,r_ans,min_ans;
- bool vis[N][N],flag;
- inline void read(int &x)
- {
- x=; char ch=getchar();
- while (ch<''||ch>'') ch=getchar();
- while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
- }
- inline void l_DFS(int x,int y,int w,int s)
- {
- if (flag) return;
- if (x==e_x&&y==e_y) { l_ans=s; flag=; return; }
- for (int i=;i<;++i)
- {
- int xx=x+fx[l[w][i]],yy=y+fy[l[w][i]];
- if (xx<=||yy<=||xx>n||yy>m) continue;
- if (a[xx][yy]=='#') continue;
- l_DFS(xx,yy,l[w][i],s+);
- }
- }
- inline void r_DFS(int x,int y,int w,int s)
- {
- if (flag) return;
- if (x==e_x&&y==e_y) { r_ans=s; flag=; return; }
- for (int i=;i<;++i)
- {
- int xx=x+fx[r[w][i]],yy=y+fy[r[w][i]];
- if (xx<=||yy<=||xx>n||yy>m) continue;
- if (a[xx][yy]=='#') continue;
- r_DFS(xx,yy,r[w][i],s+);
- }
- }
- inline void BFS(int s_x,int s_y)
- {
- memset(step,,sizeof(step));
- memset(vis,true,sizeof(vis));
- int head=,tail=;
- q[][]=s_x; q[][]=s_y; step[s_x][s_y]=; vis[s_x][s_y]=;
- while (head<tail)
- {
- int x=q[++head][],y=q[head][];
- if (x==e_x&&y==e_y) { min_ans=step[x][y]; return; }
- for (int i=;i<;++i)
- {
- int xx=x+fx[i],yy=y+fy[i];
- if (xx<=||yy<=||xx>n||yy>m) continue;
- if (a[xx][yy]=='#'||!vis[xx][yy]) continue;
- q[++tail][]=xx; q[tail][]=yy; step[xx][yy]=step[x][y]+; vis[xx][yy]=;
- }
- }
- }
- int main()
- {
- read(t);
- while (t--)
- {
- read(m); read(n);
- for (i=;i<=n;++i)
- for (j=;j<=m;++j)
- {
- cin>>a[i][j];
- if (a[i][j]=='S') s_x=i,s_y=j;
- if (a[i][j]=='E') e_x=i,e_y=j;
- }
- if (s_x==) w=; if (s_x==n) w=; if (s_y==) w=; if (s_y==m) w=;
- flag=; l_DFS(s_x,s_y,w,);
- flag=; r_DFS(s_x,s_y,w,);
- BFS(s_x,s_y);
- printf("%d %d %d\n",l_ans,r_ans,min_ans);
- }
- return ;
- }
POJ 3278&&2049&&3083的更多相关文章
- 【BFS】POJ 3278
POJ 3278 Catch That Cow 题目:你要去抓一头牛,给出你所在的坐标和牛所在的坐标,移动方式有两种:要么前一步或者后一步,要么移动到现在所在坐标的两倍,两种方式都要花费一分钟,问你最 ...
- BFS POJ 3278 Catch That Cow
题目传送门 /* BFS简单题:考虑x-1,x+1,x*2三种情况,bfs队列练练手 */ #include <cstdio> #include <iostream> #inc ...
- POJ 3278 Catch That Cow(赶牛行动)
POJ 3278 Catch That Cow(赶牛行动) Time Limit: 1000MS Memory Limit: 65536K Description - 题目描述 Farmer J ...
- catch that cow POJ 3278 搜索
catch that cow POJ 3278 搜索 题意 原题链接 john想要抓到那只牛,John和牛的位置在数轴上表示为n和k,john有三种移动方式:1. 向前移动一个单位,2. 向后移动一个 ...
- [ACM训练] 算法初级 之 搜索算法 之 广度优先算法BFS (POJ 3278+1426+3126+3087+3414)
BFS算法与树的层次遍历很像,具有明显的层次性,一般都是使用队列来实现的!!! 常用步骤: 1.设置访问标记int visited[N],要覆盖所有的可能访问数据个数,这里设置成int而不是bool, ...
- poj 3278 Catch That Cow (bfs)
题目:http://poj.org/problem?id=3278 题意: 给定两个整数n和k 通过 n+1或n-1 或n*2 这3种操作,使得n==k 输出最少的操作次数 #include<s ...
- POJ 3278 Catch That Cow(BFS,板子题)
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 88732 Accepted: 27795 ...
- POJ 3278 Catch That Cow(模板——BFS)
题目链接:http://poj.org/problem?id=3278 Description Farmer John has been informed of the location of a f ...
- POJ - 3278
题目链接:http://poj.org/problem?id=3278 ac代码: #include <iostream>#include <stdio.h>#include ...
随机推荐
- vue-router 手势滑动触发返回
vue-router的路由变换只存在“变换前”和“变换后”,不存在“切换中”的状态,所以做不到大多数app(微信那样的)在滑动过程中让界面跟随手指移动.但滑动事件还是可以监听的,我们可以在滑动之后再触 ...
- c#中的数据类型简介(委托)
什么是委托? 委托是一种类型,它封装了一类方法,这些方法具有相同的方法签名(signature)和返回类型.定义听起来有点拗口,首先可以确定委托是一种数据类型,那么什么是方法签名,其实就是指方法的输入 ...
- 误删mysql表物理文件的解决方法(不涉及恢复数据)
该方法只介绍了如何救回这个表名(数据不恢复) 如果想要恢复原来数据 直接用extundelete把文件恢复后放回去即可 并且是适用于平时没有全备的情况下 如果有全备 直接那全备的frm和idb文件放 ...
- 再谈全局网HBase八大应用场景
摘要: HBase可以说是一个数据库,也可以说是一个存储.拥有双重属性的HBase天生就具备广阔的应用场景.在2.0中,引入了OffHeap降低了延迟,可以满足在线的需求.引入MOB,可以存储10M左 ...
- WCF 基于 WinForm 宿主 发布
ServiceHost Host = new ServiceHost(typeof(ServiceHTTP)); //绑定 System.ServiceModel.Channels.Binding h ...
- Audit log report
- Django商城项目笔记No.5用户部分-注册接口-短信验证码
Django商城项目笔记No.4用户部分-注册接口-短信验证码 短信验证码也保存在redis里(sms_code_15101234567) 在views中新增SMSCodeView类视图,并且写出步骤 ...
- [游记] Noip 2018
飞雪连天射白鹿, 笑书神侠倚碧鸳 $ 2018/12/14 $ 经历了 \(noip\) 玩完的心态爆炸之后,还是决定稍微写一下游记记录一下\(QAQ\),以免以后就忘了. 然后打算先写个框架之后再慢 ...
- Spark项目之电商用户行为分析大数据平台之(三)大数据集群的搭建
Zookeeper集群搭建 http://www.cnblogs.com/qingyunzong/p/8619184.html Hadoop集群搭建 http://www.cnblogs.com/qi ...
- 【转】 python中 * 的用法
转自:https://www.cnblogs.com/jony7/p/8035376.html 1.表示乘号 2.表示倍数,例如: def T(msg,time=1): print((msg+' ...