连连看

Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 126 Accepted Submission(s): 63
 
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
 
Code
 
 
 1 #include <stdio.h>
 2 #define N 1000
 3 /*
 4     map[N + 5][N + 5]: the input matrix
 5     n: the number of rows
 6     m: the number of column
 7     ex: end of x
 8     ey: end of y
 9     destination point is (ex, ey)
10     flag: when can arrive the destination, flag = 1
11 */
12 int map[N + 5][N + 5], n, m, ex, ey, flag;
13 
14 /*
15     dx[5]: the x of the directory
16     dy[5]: the y of the directory
17     such as, (dx[1], dy[1]), that is (0, -1), means moving left.(maybe u will feel confuse, but it is)
18     dir: directory
19         dir = 1, means left
20         dir = 2, means up
21         dir = 3, means down
22         dir = 4, means right
23     bx: begin of x
24     by: begin of y
25     start point is (bx, by)
26     ct: count of turning
27     
28 */
29 int dx[5] = {0, 0, -1, 1, 0};
30 int dy[5] = {0, -1, 0, 0, 1};
31 void dfs(int bx, int by, int ct, int dir)
32 {
33     int i;
34     //arrive the desitanation
35     if (flag == 1)    return;
36     //mean u turn to many 
37     if (ct >= 3)    return;
38     //this is crucial, without this, u will wrong
39     if (ct == 2)
40          if (dir == 1 && (bx != ex || by < ey) || dir == 2 && (bx < ex || by != ey) || dir == 3 && (bx > ex || by != ey) || dir == 4 && (bx != ex || by > ey))
41             return;
42     //out of index
43     if(bx <= 0 || bx > n || by <= 0 || by > m)
44         return;
45     //arrive the destination, note that dir =0 means this is the first time
46     if (dir != 0 && bx == ex && by == ey)
47     {
48         flag = 1;
49         return;
50     }
51     //u will be blocked when u come across a non-zero interger
52     if (dir != 0 && map[bx][by] != 0)
53         return;
54     //from all of the directions
55     for (i = 1; i <= 4; i++)
56     {
57         if (dir == 0 || i == dir)
58             dfs(bx + dx[i], by + dy[i], ct, i);
59         else if (i + dir != 5)
60             dfs(bx + dx[i], by + dy[i], ct + 1, i);
61     }
62 }
63 void main()
64 {    
65     //q: the num of the query
66     int q, i, j, bx, by;
67     while (scanf("%d %d", &n, &m) && (m || n))
68     {
69         //input
70         for (i = 1; i <= n; i++)
71             for (j = 1; j <= m; j++)
72                 scanf("%d", &map[i][j]);
73             scanf("%d", &q);
74         for (j = 1; j <= q; j++)
75         {
76             scanf("%d %d %d %d", &bx, &by, &ex, &ey);
77             //the input points is same or there is a zero or the two numbers are different
78             if (bx == ex && bx == ey || map[bx][by] == 0 || map[bx][by] == 0 || map[bx][by] != map[ex][ey])
79                 puts("NO");
80             else
81             {
82                 flag = 0;
83                 dfs (bx, by, 0, 0);
84                 if (flag == 1)
85                     puts("YES");
86                 else
87                     puts("NO");
88             }
89         }
90     }
91 }

 

The code is in detail, what I want stress is that the row and column are different to the coodinate.
posted on 2013-03-20 15:57  MrMission  阅读(733)  评论(0编辑  收藏  举报