hdu 1175(BFS&DFS) 连连看
题目在这里:http://acm.hdu.edu.cn/showproblem.php?pid=1175
大家都很熟悉的连连看,原理基本就是这个,典型的搜索.这里用的是广搜.深搜的在下面
与普通的搜索比不同的是要求转折的线不能转折超过两次,就是在结构体中多开一个step(储存转折的次数)和一个dir(记录此刻的方向)
方向初始为-1,当行走一步后的方向与走之前不同的时候,step就应该加一,
然后还要注意的是为了保证得到的是所有的路线中转折次数最小的,这里的visit数组要用来保存每个点的最小转折次数,
所以初始化应该为很大
具体的看code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<climits>
using namespace std;
int map[][],visit[][];
struct point {
int x,y;
int step,dir;//记录转折次数与方向
} ;
int dx[]={,,,-};
int dy[]={,-,,};
int n,m,ex,ey;
int bfs(int sx,int sy)
{
int i;
queue<point>Q;
point next,now;
now.x=sx;now.y=sy;
now.step=;
now.dir=-;
Q.push(now);
while (!Q.empty())
{
now=Q.front();
Q.pop();
if (now.x==ex&&now.y==ey)
return ;
for (i=;i<;i++)
{
next.x=now.x+dx[i];
next.y=now.y+dy[i];
next.step=now.step;
next.dir=i;
if (next.dir!=now.dir&&now.dir!=-)//方向发生变化就加一,但是是第一步的时候并不算是转折
next.step++;
if ((next.x<=n&&next.x>=)&&(next.y<=m&&next.y>=)&&(map[next.x][next.y]==||(next.x==ex&&next.y==ey)))
{
if (next.step<)
{
if (next.step<visit[next.x][next.y]) //让visit数组保存的是到每一点的最小转折次数
{
visit[next.x][next.y]=next.step;
Q.push(next);
}
}
}
}
}
return ;
}
int main()
{
int i,j,t,sx,sy;
while (~scanf("%d %d",&n,&m))
{
if (n==&&m==)
break;
for (i=;i<=n;i++){
for (j=;j<=m;j++){
scanf("%d",&map[i][j]);
}
}
scanf("%d",&t);
while (t--)
{
cin>>sx>>sy>>ex>>ey;
if (sx==ex&&sy==ey)
{
printf("NO\n");
continue;
}
if (map[sx][sy]==||map[ex][ey]==||map[sx][sy]!=map[ex][ey])//这些特殊情况不要漏掉
{
printf("NO\n");
continue;
}
for(i = ; i <= n; i++)
for(j = ; j <= m; j++)
visit[i][j] = ; //初始化为一个很大的数
if (bfs(sx,sy)==)
printf("YES\n");
else
printf("NO\n");
} }
return ;
}
感觉这题深搜比广搜好想一些
无非就是多加了判断条件,注意回溯就行
code
#include<cstdio>
#include<cstring>
using namespace std;
int map[][],visit[][];
int n,m,ex,ey;
int dx[]={,,,-};
int dy[]={,,-,};
int ans;
void dfs(int fx,int fy,int dir,int step)
{
int x,y,i;
if (ans==)return ;
if (step>)return ;
if (step==&&fx-ex!=&&fy-ey!=)return ;
if (fx==ex&&fy==ey&&step<=)
{
ans=;
return ;
}
for (i=;i<;i++)
{
x=fx+dx[i];
y=fy+dy[i];
if (y<=||y>m||x<=||x>n)continue;
if (x==ex&&y==ey)
;
else if (map[x][y]!=)
continue;
if (visit[x][y]!=)continue;
//if (step>=3)continue;
if (dir!=i&&dir!=-)
step++;
visit[x][y]=;
dfs(x,y,i,step);
visit[x][y]=; //注意回溯,step也要回溯
if (i!=dir&&dir!=-)
step--;
}
}
int main()
{
int i,t,j,sx,sy;
while (~scanf("%d %d",&n,&m))
{
if (n==&&m==)
break;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
scanf("%d",&map[i][j]);
}
scanf("%d",&t);
while (t--)
{
memset(visit,,sizeof(visit));
scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
if (sx==ex&&sy==ey)
{
printf("NO\n");
continue;
}
if (map[sx][sy]!=map[ex][ey]||map[sx][sy]==||map[ex][ey]==)
{
printf("NO\n");
continue;
}
ans=;
visit[sx][sy]=;
dfs(sx,sy,-,); if (ans==)
printf("YES\n");
else
printf("NO\n");
}
}
return ;
}
hdu 1175(BFS&DFS) 连连看的更多相关文章
- hdu 1983(BFS+DFS) 怪盗Kid
http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...
- hdu 1175 bfs+priority_queue
连连看 如上图所示如果采用传统bfs的话,如果按照逆时针方向从(1,1)-->(3,4)搜索,会优先选择走拐四次弯的路径导致ans错误: Time Limit: 20000/10000 MS ( ...
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU - 1175 bfs
思路:d[x][y][z]表示以z方向走到(x, y)的转弯次数. 如果用优先队列会超时,因为加入队列的节点太多,无用的节点不能及时出队,会造成MLE,用单调队列即可. AC代码 #include & ...
- hdu 1175
#include <iostream> #include <string> #include <stdio.h> using namespace std; int ...
- POJ 2227 The Wedding Juicer (优先级队列+bfs+dfs)
思路描述来自:http://hi.baidu.com/perfectcai_/item/701f2efa460cedcb0dd1c820也可以参考黑书P89的积水. 题意:Farmer John有一个 ...
- 邻结矩阵的建立和 BFS,DFS;;
邻结矩阵比较简单,, 它的BFS,DFS, 两种遍历也比较简单,一个用队列, 一个用数组即可!!!但是邻接矩阵极其浪费空间,尤其是当它是一个稀疏矩阵的时候!!!-------------------- ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- hdu 4531 bfs(略难)
题目链接:点我 第一次不太清楚怎么判重,现在懂了,等下次再做 /* *HDU 4531 *BFS *注意判重 */ #include <stdio.h> #include <stri ...
随机推荐
- cgi调用linux系统命令
1.例如:建一个目录:system("mkdir yourdir").(1)首先:要用root用户如果cgi中要用root用户,则必须在boa.conf文件中配置,将User no ...
- javascript学习笔记(三):运算符、循环语句
javascript的运算符.条件语句.循环语句的使用方法大部分和c语言类似,但是值得注意的是,运算符中"=="和"==="的使用方法和c语言有区别:在java ...
- 修改.net反编译的dll
用.Net reflector 打开,配合reflexil工具. 有两种修改方法. 1.重写,试过,但不好用. 2.修改IL指令 一般只需修改简单的if判断. 方法:找到需要修改的行,把brfalse ...
- ffmpeg编码中的二阻塞一延迟
1. avformat_find_stream_info接口延迟 不论是减少预读的数据量,还是设置flag不写缓存,我这边都不实用,前者有风险,后者会丢帧,可能我还没找到好姿势,记录在此,参考:htt ...
- shell中参数的传递
1.命令行参数 向shell脚本传递数据的最基本方式是使用命令行参数. (1) 读取参数 读取输入的参数的变量为位置参数,位置参数通过标准数字表示, 其中$0为程序名称,$1为第一个参数,$2为第二个 ...
- Gym - 101911C Bacteria (规律题)
传送门:点我 Time limit2000 ms Memory limit262144 kB Recently Monocarp has created his own mini-laboratory ...
- sourceforge
sourceforge SourceForge.net,又称SF.net,是开源软件开发者进行开发管理的集中式场所. SourceForge.net由VA Software提供主机,并运行Source ...
- JavaScript各种继承方式(三):组合继承(combination inheritance)
一 原理 组合继承仅仅是同时使用了原型链继承和构造函数继承. 具体做法是,将父类的实例作为子类的构造函数的原型对象,并在子类的构造函数中调用父类的构造函数. function Fruit(name){ ...
- python中类变量和成员变量、局部变量总结
class Member(): num= #类变量,可以直接用类调用,或用实例对象调用 def __init__(self,x,y): self.x=x #实例变量(成员变量),需要它是在类的构造函数 ...
- Linux系统声卡问题
问题:Linux系统中有声卡设备,但是听不到声音 一.声卡驱动没有安装 1.通过插拔声卡查出声卡驱动 2.在相应的kernel中编译内核 修改保存.config文件,然后进行编译 make -j ma ...