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 ...
随机推荐
- Flutter——设置appBar的高度
使用脚手架Scaffold可以设置AppBar,想要设置高度,在AppBar外包一层PreferredSize,设置preferredSize的属性为想要的高度即可. Scaffold( appBar ...
- excel、xls文件读写操作
python 常用的excel.xls文件读写操作,有两个模块 xlrd:读 xlwt:写 本次先写一个读的例子: class CaseData(object): def __init__(self, ...
- 有关于《Linux C编程一站式学习》(备份)
Linux C编程一站式学习 -- PDF版本,共37章: Linux C编程一站式学习 -- 在线版,来自灰狐: Linux C编程一站式学习 -- 在线版,来自亚嵌教育: Linux C一站式学习 ...
- (转)在.net中检索HTTP请求
原文转载:https://www.west-wind.com/presentations/dotnetWebRequest/dotnetWebRequest.htm HTTP内容检索是应用程序的重要组 ...
- CentOS 7 环境下 GitLab安装部署以及账号初始化
1. 安装相关依赖 yum install curl policycoreutils openssh-server openssh-clients -y # 确保sshd启动(正常情况下, sshd是 ...
- chmod chown llinux文件及目录的权限介绍
linux 文件或目录的读.写.执行权限说明: chmod :设置文件或目录权限. u:所有者 g:所在组 o:其他组 a:所有人(u.g.o的总和) chmod -R 文件1/文件2….. ...
- [Hive_1] Hive 基本概念
Hive 系列01 Hive 简介 & Hive 应用场景 & Hive 与 Hadoop 的关系 & Hive 与传统数据库对比 1. Hive 简介 [ 官方介绍 ] Ap ...
- MySQL主从复制半同步复制原理及搭建
在MySQL5.5之前的版本中,MySQL的复制是异步复制,主库和从库的数据之间存在一定的延迟,比如网络故障等各种原因,这样子容易存在隐患就是:当在主库写入一个事务成功后并提交了,但是由于从库延迟没有 ...
- leetcode 121 买卖股票的最佳时机
题目 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票. ...
- Ecstore Nginx Rewrite(去掉链接中的index.php) ECSTORE 伪静态
一.修改 nginx.conf文件,添加如下代码: if ($request_uri ~ (.+?\.php)(|/.+)$ ){ break; } if (!-e $request_filename ...