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

    题目地址https://www.acwing.com/problem/content/1252/

    题目描述

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

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

    1.png

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

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

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

    输入格式

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

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

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

    输出格式

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

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

    数据范围

    1n2001≤n≤200,
    1m24000

    题解:第一眼看见这道题以为超级难,结果听大佬一讲发现就是一道裸的并查集。。。。。。

    题目问你什么时候结束,那么结束的标志就是产生一个环,那么怎么判定是否产生了一个环。这就需要并查集直接操作就可以了,如果当前这条边的两端在同一个集合中,那么就是一个环。那么剩下的就只有一个小问题了,就是并查集一般是在一维空间下,这里就需要将二维空间转换为一维空间,x*n+y,只要x,y都是从0开始的就可以了。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=210;
    const int M=24010;
    int fa[N*M],n,m;
    int find(int x){
        if(x==fa[x]) return x;
        return fa[x]=find(fa[x]);
    }
    int main(){
        cin>>n>>m;
        int ans=0;
        char ch;
        for(int i=1;i<=n*m;i++) fa[i]=i;
        for(int i=1,x,y,a,b;i<=m;i++){
            cin>>x>>y>>ch;
            a=x*n+y;
            if(ch=='D') x++;
            else y++;
            b=x*n+y;
            int ra=find(a),rb=find(b);
            if(!ans&&ra==rb) {
                ans=i;
            }
            fa[ra]=rb;
        }
        if(ans) cout<<ans;
        else cout<<"draw";
        return 0;
    } 

    写于:2020/8/22 18:10


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    asp.net保存远程图片
    JS中的转义字符
    SQL_统计某列的和
    SQL Server 出错自动回滚
    SQL中的循环语句_类似FOR循环
    转 C# 控制IE
    抓取html 写正则
    正则截取内容
    用于测试的字符串
    C#关闭IE相应的窗口 .
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13546541.html
Copyright © 2011-2022 走看看