首页 > 代码库 > hdu 1175 连连看【bfs】

hdu 1175 连连看【bfs】

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175

 

【题意】输入一个地图(由数字组成),进行q次询问,俩位置的数字若相同就连起来,输出YES,前提是拐外次数少于等于两次,否则输出NO。

 

【分析】典型的bfs,只是许久未练,有点生疏了。

 

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<queue>
 4 #include<limits.h>
 5 using namespace std;
 6 int direc[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};//方向依次为右、左、下、上
 7 int map[1005][1005],vis[1005][1005],m,n;
 8 //a为输入的2维向量,vis记录该点是否被访问过了,同时记录有转折次数,如果
 9 //新的转折次数小于以前访问时的转折次数那么更新,否则就不更新。
10 typedef struct
11 {
12     int x,y,dir,corner;//x,y,为行数列数,dir为方向,corner为转角次数。
13 }node;
14 node s,e;//记录开始和结束
15 void bfs()//宽度搜索
16 {
17     queue<node> q;
18     node cur,pre;   //用来记录当前的节点和前一个进行比较
19     s.dir = -1;//开始时无方向
20     s.corner = 0;//开始时转角次数为0
21     q.push(s);
22     while(!q.empty())
23     {
24         pre = q.front();
25         q.pop();
26         if(pre.x == e.x && pre.y == e.y)
27         {cout<<"YES"<<endl;return;}
28         for(int i = 0; i < 4; i++)//对节点的四个方向分别进行判断
29         {
30             cur.x = pre.x + direc[i][0];
31             cur.y = pre.y + direc[i][1];
32             cur.corner = pre.corner;      //令当前转角次数和前一个相同
33             cur.dir = i;                  //当前方向
34             //前一个不能使开始出,且当前方向和前一个方向不一致是转折次数自增1
35             if(pre.dir != cur.dir && pre.dir != -1) cur.corner++;
36             //判断是否出界,转角次数是否超过限制
37             if(cur.x<1||cur.y<1||cur.x>n||cur.y>m||cur.corner>2) continue;
38             //如果当前位置有数字存在,且当前位置不是终结位置,违反规则
39             if(map[cur.x][cur.y]&&!(cur.x==e.x&&cur.y==e.y)) continue;
40             if(cur.corner<vis[cur.x][cur.y])
41             {
42                 vis[cur.x][cur.y] = cur.corner;
43                 q.push(cur);
44             }
45         }
46     }
47     cout<<"NO"<<endl;
48 }
49 int main()
50 {
51     int q;
52     while(scanf("%d%d",&n,&m),n,m)
53     {
54         for(int i = 1; i <= n; i++)
55         for(int j = 1; j <= m; j++)
56         scanf("%d",&map[i][j]);
57         scanf("%d",&q);
58         while(q--)
59         {
60             scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
61             if(s.x==e.x&&s.y==e.y)//开始和结束在同一个位置
62             {cout<<"NO"<<endl;continue;}
63             //开始和结束位置没有数字或者开始和结束位置的数字不等。
64             if(!map[s.x][s.y]||!map[e.x][e.y]||(map[s.x][s.y]!=map[e.x][e.y]))
65             {cout<<"NO"<<endl;continue;}
66 
67             for(int i = 1; i <= n; i++)
68                 for(int j = 1; j <= m; j++)
69                     vis[i][j] = INT_MAX;  
70             bfs();
71         }
72     }
73     return 0;
74 }

hdu 1175 连连看【bfs】