HDU 1175 连连看 DFS 简单题

Problem Description

“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。

Input

输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。
注意:询问之间无先后关系,都是针对当前状态的!

Output

每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。

Sample Input

3 4

1 2 3 4

0 0 0 0

4 3 2 1

4

1 1 3 4

1 1 2 4

1 1 3 3

2 1 2 4

3 4

0 1 4 3

0 2 4 1

0 0 0 0

2

1 1 2 4

1 3 2 3

0 0

Sample Output

YES

NO

NO

NO

NO

YES

这道题说:”这条线不能经过其他棋子“,

是指这条线中间不能经过任何棋子,即使相同颜色的棋子也不可以。

我开始以为是中间不能经过其他颜色的棋子,wa了。

这道题还要记录方向,我是用一个Dir { int x,y }结构来记录,

分别与dx和dy的值进行比较确定方向有没有改变。

还有,在起点处往任何方向走都不算转弯,而且转弯的次数<=2,相当于

在起点处往任何方向走都算转弯,而且转弯的次数<=3.(这样处理比较方便一点).

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=1010;
 4 int n,m;
 5 bool flag;
 6 int maze[maxn][maxn];
 7 bool vis[maxn][maxn];
 8 int dx[4]={0,0,-1,1};
 9 int dy[4]={1,-1,0,0};
10 struct Point
11 {
12     int x,y;
13 };
14 Point s,e;
15 struct Dir
16 {
17     int x,y;
18 };
19 void dfs(Point cur,Dir dir,int cnt)
20 {
21     vis[cur.x][cur.y]=true;
22     if(cnt>3||flag)
23         return ;
24     if(cur.x==e.x&&cur.y==e.y)
25     {
26         printf("YES\n");
27         flag=true;//标记,不然若多条路径可以,会输出多次YES
28         return ;
29     }
30     for(int i=0;i<4;i++)
31     {
32         Point dcur;
33         dcur.x=cur.x+dx[i];
34         dcur.y=cur.y+dy[i];
35         if(dcur.x<1||dcur.x>n||dcur.y<1||dcur.y>m)
36             continue;
37         //除了终点,不能经过任何棋子
38         if(maze[dcur.x][dcur.y]&&(dcur.x!=e.x||dcur.y!=e.y))
39             continue;
40         if(vis[dcur.x][dcur.y])
41             continue;
42         Dir ddir;
43         ddir.x=dx[i];
44         ddir.y=dy[i];
45         if(dir.x==ddir.x&&dir.y==ddir.y)//判断方向有没有改变
46             dfs(dcur,ddir,cnt);
47         else
48             dfs(dcur,ddir,cnt+1);
49         vis[dcur.x][dcur.y]=false;//回溯
50     }
51 }
52 int main()
53 {
54     while(scanf("%d%d",&n,&m))
55     {
56         if(n==0&&m==0)
57             break;
58         for(int i=1;i<=n;i++)
59             for(int j=1;j<=m;j++)
60                 scanf("%d",&maze[i][j]);
61         memset(vis,false,sizeof(vis));  //初始化
62         int q;
63         scanf("%d",&q);
64         Dir dir;
65         for(int j=1;j<=q;j++)
66         {
67             scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
68             if(maze[s.x][s.y]!=maze[e.x][e.y])   //起点终点不相同直接剪枝
69                 printf("NO\n");
70             else if(!maze[s.x][s.y]||!maze[s.x][s.y])  //起点终点有一个位置没有棋子直接剪枝
71                 printf("NO\n");
72             else
73             {
74                 dir.x=dir.y=0;  //初始化起点方向
75                 flag=false;    //设立标记
76                 dfs(s,dir,0);
77                 vis[s.x][s.y]=false;   //回溯
78                 if(!flag)
79                     printf("NO\n");  //若不可以要输出NO,这一步不要忘了
80             }
81         }
82     }
83     return 0;
84 }

提交代码

时间: 2024-08-05 23:19:50

HDU 1175 连连看 DFS 简单题的相关文章

HDU - 1175 连连看 DFS (记录方向)

连连看HDU - 1175 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

HDU 1175 连连看(DFS)

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

【dfs】hdu 1175 连连看

[dfs]hdu 1175 连连看 题目链接:hdu 1175 连连看 题目大意 连连看,问能否成功? 题意很简单,就是我们平时玩的连连看的游戏规则,貌似dfs和bfs都能做,笔者就做了个dfs(好想),超时了好几次,原因是dfs(int d)与终点的d重载矛盾了,所以还是要小心. 说一下思路 神器的剪枝:if(t==2&&x!=c&&y!=d) return;这一部剪枝妙笔回春,9000+MS优化到100+MS啊:如果转了2次,但是目标与当前位置不在同一行或同一列就不满足

hdu 1175 连连看 (深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以消掉.还有一个要注意的地方的就是转弯.转弯的次数不超过两次,这两个棋子才可以在棋盘上消去~ 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

hdu 5310 Souvenir (简单题)

这是一道稍微仔细想想就可以做出来的简单题,而我wa了两次,这也是把它写上来的原因,只是因为我没有认真想,还是不够仔细啊,还是很马虎啊,不能慌张,得仔细读题,慢慢想题. 思路: 一共只有几种情况:1全部用单价p买:2全部用套装q买:3先用套装买,剩下的用单价p买 注:不必判断先用单价p再用套装(如果先用p的话就证明单价比套装更划算(买相同数量所需要的话费)) 贴代码: #include<stdio.h> #include<stdlib.h> #include<string.h&

HDU - 1175 连连看(带转弯的dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题意:代码模拟连连看(转弯数不能超过两次)并且不能绕外圈. 和前面几题大同小异,只不过要标记一下,因为连在一起的相当于这两个点没有了. 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 int dx[4]={0,1,0,-1}; 6 int dy[4]={1,0,-1,0}; 7 int m

Hdu 1175 连连看(DFS)

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu 1728相比,都要考虑转弯次数,所以在判断转弯的次数上,两者可以相互借鉴. 这一点应该不难想到,在搜索前就应判断两点的值是否相等,以及两点的值中是否有0.如果不相等或其中一值为0,则可以判断是"NO". 时间虽是10000ms,但只是这样,还是超时. 后来又加了一个数组walk[][],用

HDU 1010 Tempter of the Bone DFS 简单题 注意剪枝

题意:一只小狗要刚好在t时刻从起点都到终点,问可不可以. 注意剪枝. 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 int maze[9][9]; 6 bool vis[9][9]; 7 int n,m,t; 8 bool ans; 9 struct Point 10 { 11 int x,y; 12 }; 13 int dx[4]={0,0,-1,1}