• 连连看 杭电1175


    连连看

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 11866    Accepted Submission(s): 3115


    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
     
    解题思路:
        题目要求是少于 2 次转折,并非最短路,所以单纯的广搜,最终会导致 WA,原因在于如果你走最短路走到了,但转折次数多余两次,不合要求,继续寻找,找到一条长的,转折次数不大于 2 次的路,但经过了走最短路时已标记的点,就会导致走不了,而错过正确答案!
        解决办法就是不标记路径而标记转折次数!
     
    解题代码及注释:
    View Code
      1 // File Name: /media/文档/源程序/实验室/4B广搜.cpp
      2 // Author: sheng
      3 // Created Time: 2013年03月15日 星期五 19时17分15秒
      4 
      5 #include <iostream>
      6 #include <string.h>
      7 using namespace std;
      8 typedef long long LL;
      9 # define Max 1005
     10 
     11 int n, m, x1, y1, x2, y2;
     12 int tag[Max][Max];
     13 LL map[Max][Max];
     14 
     15 struct node
     16 {
     17     int x;
     18     int y;
     19     int s;
     20     int sign;
     21 }Link[Max * Max+1];
     22 
     23 const int x_change[] = {0, 0, -1, 1};
     24 const int y_change[] = {1, -1, 0, 0};
     25 
     26 int bfs()
     27 {
     28     int rear, top, S;
     29     rear = top = S = 0;
     30     int X, Y, sign, sign1;
     31     Link[rear ++] = (node){x1, y1, S, -1};
     32 
     33     while(rear > top)
     34     {
     35         if (Link[top].x == x2 && Link[top].y == y2)///当到达终点时返回真值1
     36             return 1;
     37 
     38         X = Link[top].x;
     39         Y = Link[top].y;
     40         S = Link[top].s;
     41         sign = Link[top++].sign;
     42         for (int i = 0; i < 4; i ++)
     43         {
     44             int xx = X + x_change[i];
     45             int yy = Y + y_change[i];
     46             if(sign != i && sign != -1)///记录转折的方向,当前方向与之前的方向不同时,标记转折的结构体加一
     47             {        
     48                 Link[rear].s = S + 1;
     49             }
     50             else
     51             {
     52                 Link[rear].s = S;
     53             }
     54             ///判断元素坐标是否出界,转角次数是否超出规则
     55             if (xx >= n || yy >= m || xx < 0 || yy < 0 || Link[rear].s > 2)
     56                 continue;
     57             ///当前点有元素,但不是终点是继续循环
     58             if ( map[xx][yy] && !(xx == x2 && yy == y2))
     59                 continue 60             ///通过比较转折次数来控制是否能走,而不用标记
     61             if (tag[xx][yy] > Link[rear].s)
     62             {/////当再次回到该点时,由于转折次数不断累加,就会超出2的限制,则此点将不再进入队列
     63                 tag[xx][yy] = Link[rear].s;
     64                 Link[rear].x = xx;
     65                 Link[rear].y = yy;
     66                 Link[rear++].sign = i;
     67             }
     68         }
     69     }
     70     return 0;
     71 }
     72 
     73 int main ()
     74 {
     75     int t, i, j;
     76     while (cin >> n >> m)
     77     {
     78     
     79         if( !n && !m)
     80             break;
     81         for (i = 0; i < n; i ++)
     82         {
     83             for (j = 0; j < m; j ++)
     84                 cin >> map[i][j];
     85         }
     86         cin >> t;
     87         while (t--)
     88         {
     89             cin >> x1 >> y1 >> x2 >> y2;
     90             x1 = x1 - 1;
     91             y1 = y1 - 1;
     92             x2 = x2 - 1;
     93             y2 = y2 - 1;
     94             for (i = 0; i < n; i ++)
     95             {
     96                 for (j = 0; j < m; j ++)
     97                     tag[i][j] = 1000; ////使转折次数最大
     98             }
     99             ///当元素不等时,元素为 0 时, 起始处与终点处坐标相等时,直接输出 NO ,剪掉这一快
    100             if (map[x1][y1] != map[x2][y2] || !map[x1][y1] || !map[x2][y2] || (x1 == x2 && y1 ==y2))
    101                 cout <<"NO"<<endl;
    102             else if(bfs())
    103                 cout << "YES" << endl;
    104             else  cout << "NO" << endl;
    105         }
    106     }
    107     return 0;
    108 }

    改正之前的代码:

    View Code
      1 // File Name: /media/文档/源程序/实验室/4B广搜.cpp
      2 // Author: sheng
      3 // Created Time: 2013年03月15日 星期五 19时17分15秒
      4 
      5 #include <iostream>
      6 #include <string.h>
      7 using namespace std;
      8 typedef long long LL;
      9 # define Max 1005
     10 
     11 int n, m, x1, y1, x2, y2;
     12 int tag[Max][Max];
     13 LL map[Max][Max];
     14 
     15 struct node
     16 {
     17     int x;
     18     int y;
     19     int s;
     20     int sign;
     21 }Link[Max * Max+1];
     22 
     23 const int x_change[] = {0, 0, -1, 1};
     24 const int y_change[] = {1, -1, 0, 0};
     25 
     26 int bfs()
     27 {
     28     int rear, top, S;
     29     rear = top = S = 0;
     30     int X, Y, sign, sign1;
     31     Link[rear ++] = (node){x1, y1, S, 0};
     32 
     33     while(rear > top)
     34     {
     35         /*
     36         cout<<"                       "<< Link[top].sign<< "      "<<Link[top].s<<endl;
     37         cout<<"                rear = "<<rear<<"      top = "<<top<<endl;
     38         cout<<"                Link[top].x = "<<Link[top].x<<"   Link[top].y = "<<Link[top].y<<endl;
     39         */
     40         if (Link[top].x == x2 && Link[top].y == y2 && Link[top].s <= 2)
     41             return 1;
     42 
     43         X = Link[top].x;
     44         Y = Link[top].y;
     45         S = Link[top].s;
     46         sign = Link[top++].sign;
     47         for (int i = 0; i < 4; i ++)
     48         {
     49             int xx = X + x_change[i];
     50             int yy = Y + y_change[i];
     51             if (xx >= n || yy >= m || xx < 0 || yy < 0)
     52                 continue;
     53             if ( (!map[xx][yy] || (xx == x2 && yy == y2)) && !tag[xx][yy])
     54             {
     55                 switch(i)
     56                 {
     57                     case 0: sign1 = 1;
     58                         break;
     59                     case 1: sign1 = 2;
     60                         break;
     61                     case 2: sign1 = 3;
     62                         break;
     63                     case 3: sign1 = 4;
     64                         break;
     65                 }
     66                 tag[xx][yy] = 1;
     67                 Link[rear].x = xx;
     68                 Link[rear].y = yy;
     69                 Link[rear].sign = sign1;
     70                 if(sign != sign1 && sign)
     71                 {        
     72                         Link[rear].s = S + 1;
     73                 }
     74                 else
     75                 {
     76                     Link[rear].s = S;
     77                 }
     78                 rear ++;
     79             }
     80         }
     81     }
     82     return 0;
     83 }
     84 
     85 int main ()
     86 {
     87     int t, i, j;
     88     while (cin >> n >> m)
     89     {
     90     
     91         if( !n || !m)
     92             break;
     93         for (i = 0; i < n; i ++)
     94         {
     95             for (j = 0; j < m; j ++)
     96                 cin >> map[i][j];
     97         }
     98         cin >> t;
     99         while (t--)
    100         {
    101             cin >> x1 >> y1 >> x2 >> y2;
    102             x1 = x1 - 1;
    103             y1 = y1 - 1;
    104             x2 = x2 - 1;
    105             y2 = y2 - 1;
    106             memset(tag, 0 ,sizeof (tag));
    107             if(map[x1][y1] == map[x2][y2] && map[x1][y1] && map[x2][y2])
    108             {
    109                 if(bfs())
    110                     cout << "YES" << endl;
    111                 else  cout << "NO" << endl;
    112             }
    113             else cout << "NO" << endl;
    114         }
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    Python图形编程探索系列-07-程序登录界面设计
    英语初级学习系列-05-阶段1总结
    Python图形编程探索系列-06-按钮批量生产函数
    英语初级学习系列-04-年龄
    Python图形编程探索系列-05-用控制变量构建对话程序
    Python图形编程探索系列-04-网上图片与标签组件的结合
    Python图形编程探索系列-03-标签组件(Label)
    Python解释数学系列——分位数Quantile
    Python图形编程探索系列-02-框架设计
    Python图形编程探索系列-01-初级任务
  • 原文地址:https://www.cnblogs.com/shengshouzhaixing/p/2969943.html
Copyright © 2020-2023  润新知