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 ...
随机推荐
- IDEA报错:Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. ('crmWatcherService'错误)
单表插入项目,插入前正常,插入后运行webapplication报错: run: debug: 于webapplication报错: Injection of autowired dependenci ...
- 使用IDEA创建Java Web项目并部署
前面给大家介绍了IDEA的安装和基本配置,睡觉前Alan再给大家分享一下使用IDEA创建Java Web并部署访问. 打开IDEA,File>New>Project,进入Java Ente ...
- LeetCode题解之Merge Two Sorted Lists
1.题目描述 2.题目分析 题目要求合并有序的两个链表,要求不能额外申请空间. 3.代码 ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { i ...
- python之绘制图形库turtle
关于绘制图形库turtle# 画布上,默认有一个坐标原点为画布中心的坐标轴(0,0),默认"standard"模式坐标原点上有一只面朝x轴正方向小乌龟 一:海龟箭头Turtle相关 ...
- UNIX高级环境编程(15)进程和内存分配 < 故宫角楼 >
故宫角楼是很多摄影爱好者常去的地方,夕阳余辉下的故宫角楼平静而安详. 首先,了解一下进程的基本概念,进程在内存中布局和内容. 此外,还需要知道运行时是如何为动态数据结构(如链表和二叉树)分配额外内 ...
- selenium - pycharm三种案例运行模式
1.unittest 运行单个用例 (1)将鼠标放到对应的用例,右键运行即可 2.unittest运行整个脚本案例 将鼠标放到if __name__ == "__main__": ...
- pycharm 中脚本执行的3种模式
https://blog.csdn.net/chenmozhe22/article/details/81700504
- windows中使用git和开源中国
现学现卖,学了忘忘了学. 非常感谢OSC提供了这么好的一个国内的免费的git托管平台.这里简单说下TortoiseGit操作的流程.很傻瓜了首先你要准备两个软件,分别是msysgit和tortoise ...
- SDN2017 第四次作业
1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控制器 ht ...
- JSONP方法解决跨域请求
Ajax跨域请求的问题 跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子 <!D ...