【HDU 1175】连连看(DFS)

来源:互联网 发布:linux 添加组 编辑:程序博客网 时间:2024/06/05 01:09

Description

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

Input

输入数据有多组。每组数据的第一行有两个正整数n,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

题目大意

中文题

思路

卡了一下午,在判断转折次数上一直出错,最后无奈去看了题解,重新对着题解敲了一遍。其实判断转折次数只要判断下一次行走的方向和上一次行走的方向是否相同即可,因为我们定义了dir[x][y]数组用于表示前进的方向所以只需要判断x的值和行进前的x值是否相等就可以判断有没有转折。另外一个难点就是剪枝,很容易发现如果转折次数为2次的时候如果目标点和当前所在的点不在同一个直线上,那么必定还要转折一次,这种情况可以直接返回。

代码

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=1005;int map[maxn][maxn],n,m,x1,y1,x2,y2,flag,q;int vis[maxn][maxn];void dfs(int x,int y,int z,int cnt)//z表示前进的方向,1:up,2:down,3:left,4:right {    if(flag) return;    if(cnt>2) return;    if(x<=0||x>n||y<=0||y>m) return;    if(x==x2&&y==y2)    {        flag=1;        return;    }    if(cnt==2)    {        if(!(z==1&&x>x2&&y==y2||z==2&&x<x2&&y==y2||z==3&&y>y2&&x==x2||z==4&&y<y2&&x==x2)) return;    }    if(map[x][y]!=0) return;    if(vis[x][y]) return;    vis[x][y]=1;    if(z == 1)//确定一个前进方向,对4个方向分别dfs     {        dfs(x-1,y,1,cnt);        dfs(x+1,y,2,cnt+1);        dfs(x,y-1,3,cnt+1);        dfs(x,y+1,4,cnt+1);    }    else if(z == 2)    {        dfs(x-1,y,1,cnt+1);        dfs(x+1,y,2,cnt);        dfs(x,y-1,3,cnt+1);        dfs(x,y+1,4,cnt+1);    }    else if(z == 3)    {        dfs(x-1,y,1,cnt+1);        dfs(x+1,y,2,cnt+1);        dfs(x,y-1,3,cnt);        dfs(x,y+1,4,cnt+1);    }    else if(z == 4)    {        dfs(x-1,y,1,cnt+1);        dfs(x+1,y,2,cnt+1);        dfs(x,y-1,3,cnt+1);        dfs(x,y+1,4,cnt);    }    vis[x][y] = 0;}int main(){    while(~scanf("%d %d",&n,&m))    {        if(!n&&!m) break;        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                scanf("%d",&map[i][j]);            }        }        scanf("%d",&q);        for(int i=1;i<=q;i++)        {            flag=0;            memset(vis,0,sizeof(vis));            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);            if(x1==x2&&y1==y2&&map[x1][y1]!=0)                printf("NO\n");            else if(map[x1][y1]==map[x2][y2]&&map[x1][y1])            {                dfs(x1-1,y1,1,0);                dfs(x1+1,y1,2,0);                dfs(x1,y1-1,3,0);                dfs(x1,y1+1,4,0);                if(flag) printf("YES\n");                else printf("NO\n");            }            else printf("NO\n");        }    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 餐饮新店没人气怎么办 实体店没有生意怎么办 新店开业生意不好怎么办 壁纸店没有生意怎么办? 开业第一天人少怎么办 开业第一天没人怎么办 被辞退心里难受怎么办 幼犬脚受伤了怎么办 脚掌发硬发干怎么办? 狗舔了伤口怎么办 工地打工不给钱怎么办 转运珠破了怎么办 凉鞋鞋扣老是掉怎么办 凉鞋扣子总是掉怎么办 水泥制品厂怎么办环评 深色木地板显脏怎么办 地板深了怎么办啊? 墙漆掉在家具上怎么办 皮质鞋子染色了怎么办 腹部抽脂后左右不对称怎么办 文化自信我们该怎么办 法庭把案子拖着怎么办 高中分班考差了怎么办 探索者软件打不开了怎么办 蔗阳伞没有底座怎么办 大伞没有底座怎么办 母乳过敏的湿疹怎么办 孩子对母乳过敏怎么办 cad图分解不了怎么办 衣柜宽出墙体怎么办 楼层大门锁住了怎么办 黄牛流口水烂嘴巴怎么办 长的小气不成熟怎么办 如果卵泡长不成熟怎么办 入了居民医保怎么办 电视没有频道了怎么办 tcl无频道请搜台怎么办 二胡声音太嘶哑怎么办 冰箱冷冻室结冰打不开怎么办 冰箱冷冻抽屉打不开怎么办 冰箱冷冻不结冰怎么办