• 【u232】围棋游戏


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    为了增强幼儿园小朋友的数数能力,小虎老师给了一个家庭游戏作业。让小虎那一块空的围棋盘,随机在一些方格中放些棋子
    (有黑白两种颜色),如果一个方格和它的上、下、左、右四个方格之一有相同颜色的棋子,则认为两个格子是相互连通的。
    这期间,要求小虎不断统计共有多少个连通块。
    如下图是一个5*9的一块棋盘,其中“.“表示空格,”*“表示黑棋子,”@“表示白棋子。则有4块连通子块。

    哥哥大虎在一边看一边想,如果棋盘是N*N的,共放了M个棋子,如何使用计算机解决这个问题呢?

    【输入格式】

    第一行两个整数:N,M 接下来有M行,每行三个整数:C X Y(0<=c<=1,1<=x,y<=n)。分别表示依次放入棋子的颜色(0表示白色,1表示黑色)、要放入格子的横坐标和格子的纵坐标。

    【输出格式】

    共M行。第i行一个整数,表示放入第i个棋子后,当前有多少个棋子连通块。

    【数据规模】

    30%数据:1<=n<=10 60%数据:1<=n<=100 100%数据:1<=m<=n*n。n<=500。

    Sample Input1

    3 5
    1 1 1
    1 1 2
    0 2 2
    1 3 1
    1 2 1
    Sample Output1

    1
    1
    2
    3
    2

    Sample Input2

    3 5
    1 1 2
    1 2 1
    1 3 2
    1 2 3
    1 2 2

    Sample Output2

    1
    2
    3
    4
    1

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u232

    【题意】

    中文题

    【题解】

    每次放下棋子之后,连通块递增1;
    看看放下去的棋子所在的位置的四周有没有和它的颜色相同的棋子;
    如果有的话,用并查集的找爸爸函数看看它们俩是不是连在一起的,如果不是连在一起的则把它们连在一起;
    然后连通块递减1;
    然后输出答案就好;
    (x,y)坐标可以一一对应一个线性的数字->(x-1)*n+y;

    【完整代码】

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int MAXN = 510;
    
    int n,m,a[MAXN][MAXN],cnt = 0;
    int f[MAXN*MAXN];
    
    int change(int x,int y)
    {
        return (x-1)*n+y;
    }
    
    int ff(int x)
    {
        if (f[x]==x) return x;
        else
            return f[x] = ff(f[x]);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        memset(a,255,sizeof a);
        rei(n);rei(m);
        rep1(i,1,m)
        {
            int c,x,y;
            rei(c);rei(x);rei(y);
            a[x][y] = c;
            cnt++;
            int temp = change(x,y);
            f[temp] = temp;
            int xx = -1,yy =-1;
            rep1(j,1,4)
            {
                int tx,ty;
                tx = x+dx[j];
                ty = y+dy[j];
                if (tx<0 || tx>n) continue;
                if (ty<0 || ty>n) continue;
                if (a[tx][ty]==a[x][y])
                {
                    xx = tx,yy = ty;
                    int temp2 = change(xx,yy);
                    int r1 = ff(temp2),r2 = ff(temp);
                    if (r1!=r2)
                    {
                        f[r1] = r2;
                        cnt--;
                    }
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    
  • 相关阅读:
    关于document.body.scrollTop用法
    set回顾
    用户登录与注册
    编写通讯录2
    利用字典的特性编写一个通讯录
    shelve模块
    shutil模块
    列表的拓展
    随机生成验证码2
    递归与欧几里得算法结合求最大公约数
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626636.html
Copyright © 2020-2023  润新知