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 ...
随机推荐
- [Objective-C] Block实现回调和简单的学习思考
初识Block的时候,总觉得其很可怕,因为看不懂其运行原理,所以用起来总是觉得不安全.关于Block的语法,等我把手里的资料全部看完,整理好再发出来.这次先看看用Block怎么实现回调. 新博客:wo ...
- [Android] 修图工具Draw9patch使用小结(附ubuntu快捷截图方法)
做项目的时候,素材图遇到点问题,然后老大大概给我讲了讲android下面图片格式.9.png和draw 9-patch的用法,感觉很清楚也很有用,所以记录一下. 原文地址请保留http://www.c ...
- UWP开发细节记录:WRL::ComPtr 的坑
WRL::ComPtr 取原始指针的地址有两种方式: operator&() 先释放原指针再取地址 GetAddressOf() 直接得到原始指针的地址 显然,operator& ...
- 【three.js练习程序】创建太阳系
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Forbidden Attack:7万台web服务器陷入被攻击的险境
一些受VISA HTTPS保护的站点,因为存在漏洞容易受到Forbidden攻击,有将近70,000台服务器处于危险之中. 一种被称为"Forbidden攻击"的新攻击技术揭露许多 ...
- 【SPL标准库专题(8)】 Datastructures:SplFixedArray
SplFixedArray主要是处理数组相关的主要功能,与普通php array不同的是,它是固定长度的,且以数字为键名的数组,优势就是比普通的数组处理更快. 类摘要 SplFixedArray im ...
- EntityFramework Code-First 简易教程(三)-------数据库初始化
现在我们来学习,当数据库初始化的时候,Code First怎样设置数据库的名字. 下面的图显示了数据库初始化的工作流程,根据传入给context基类的构造函数的参数来初始化: 根据上面的图,conte ...
- 一张思维导图纵观MySQL数据安全体系!
杨奇龙 2017-06-29 09:52:10 786 作者介绍 杨奇龙,前阿里数据库团队资深DBA,主要负责淘宝业务线,经历多次双十一,有海量业务访问DB架构设计经验.目前就职于有赞科技,负责数据库 ...
- VC 调试版(Debug Version)和发行版(Release Version)
调试是纠正或修改代码,使之可以顺利地编译.运行的过程.为此,VC IDE提供了功能强大的调试和跟踪工具. 1.1.1 调试版(Debug Version)和发行版(Release Version) 开 ...
- October 10th 2017 Week 41st Tuesday
If you focus on what you left behind you will never see what lies ahead. 如果你只顾回头看,那么你永远也看不见前方有什么. Ye ...