zoukankan      html  css  js  c++  java
  • 格子游戏(并查集)

    Alice和Bob玩了一个古老的游戏:首先画一个 n×n 的点阵(下图 n=3 )。

    接着,他们两个轮流在相邻的点之间画上红边和蓝边:

    1.png

    直到围成一个封闭的圈(面积不必为 11)为止,“封圈”的那个人就是赢家。因为棋盘实在是太大了,他们的游戏实在是太长了!

    他们甚至在游戏中都不知道谁赢得了游戏。

    于是请你写一个程序,帮助他们计算他们是否结束了游戏?

    输入格式

    输入数据第一行为两个整数 nn 和 mm。nn表示点阵的大小,mm 表示一共画了 mm 条线。

    以后 mm 行,每行首先有两个数字 (x,y)(x,y),代表了画线的起点坐标,接着用空格隔开一个字符,假如字符是 DD,则是向下连一条边,如果是 RR 就是向右连一条边。

    输入数据不会有重复的边且保证正确。

    输出格式

    输出一行:在第几步的时候结束。

    假如 mm 步之后也没有结束,则输出一行“draw”。

    数据范围

    1n2001≤n≤200,
    1m240001≤m≤24000

    输入样例:

    3 5
    1 1 D
    1 1 R
    1 2 D
    2 1 R
    2 2 D
    

    输出样例:

    4
    一个特别有意思的并查集,在这里用map和pair来完成对坐标的存储。
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<map>
     5 using namespace std;
     6 
     7 map<pair<int,int>,int> M;
     8 
     9 const int N = 40010;
    10 
    11 int p[N];
    12 
    13 int find(int x){
    14     if(x != p[x]) p[x] = find(p[x]);
    15     return p[x];
    16 }
    17 
    18 void _union(int x,int y){
    19     x = find(x);
    20     y = find(y);
    21     if(x != y) p[x] = y;
    22 }
    23 
    24 bool issame(int x, int y){
    25     return find(x) == find(y);
    26 }
    27 
    28 int n,m,t;
    29 
    30 int main(){
    31     
    32     for(int i = 0; i < N; i ++) p[i] = i;
    33     char s[4];
    34     cin >> n >> m;
    35     
    36     int ans = -1;
    37     
    38     for(int i = 0; i < m; i ++){
    39         int x,y,x1,y1;
    40         cin >> x >> y >> s;
    41         if(s[0] == 'D'){
    42             x1 = x+1;
    43             y1= y;
    44         }else{
    45             x1 = x;
    46             y1= y+1;
    47         }
    48         if(!M.count({x,y}))   M[{x,y}] = t ++; // 因为map中不存在相同的元素,所以count的返回值只能是1或者0,0代表还没有用到该点,1代表用到啦~
    49         if(!M.count({x1,y1}))  M[{x1,y1}] = t ++;
    50         if(issame(M[{x,y}],M[{x1,y1}])){
    51             if(ans == -1) ans = i + 1;
    52         }
    53         _union(M[{x,y}],M[{x1,y1}]);
    54     }
    55     if(ans == -1){
    56         printf("draw
    ");
    57     }else{
    58         printf("%d
    ",ans);
    59     }
    60     return 0;
    61 }
     
  • 相关阅读:
    Codeforces 1255B Fridge Lockers
    Codeforces 1255A Changing Volume
    Codeforces 1255A Changing Volume
    leetcode 112. 路径总和
    leetcode 129. 求根到叶子节点数字之和
    leetcode 404. 左叶子之和
    leetcode 104. 二叉树的最大深度
    leetcode 235. 二叉搜索树的最近公共祖先
    450. Delete Node in a BST
    树的c++实现--建立一棵树
  • 原文地址:https://www.cnblogs.com/ZhaoHaoFei/p/12300858.html
Copyright © 2011-2022 走看看