hdu 4775 Infinite Go(暴力)

题目链接:hdu 4775 Infinite Go

题目大意:两个人下围棋,总共走了n步,黑棋和白棋交替走,如果一片棋的上下左右被封死,那么该片棋子就会被吃掉,问说最后黑白棋各剩多少个。

解题思路:比较恶心的模拟题,相邻相同色的棋子要用并查集连接,并且要记录每片棋子还剩的空格数,如果空格数为0的话说明该片棋子被其他颜色围住,则要剔除掉,不且将相邻的位置不同色的棋空格数加1。主要是细节上的问题。

样例

8

7

5 5

4 5

3 5

3 4

4 4

3 3

4 6

18

1 3

1 4

2 2

1 5

2 4

2 3

3 1

3 2

3 5

3 4

4 2

4 3

4 4

1 6

5 3

3 3

1 10

3 3

12

1 2

1 1

2 1

2 2

1 3

3 1

2 3

1 4

3 2

3 3

4 2

2 4

4

1 1

1 2

2 2

2 1

4

2000000000 2000000000

2000000000 1999999999

1999999999 1999999999

1999999999 2000000000

8

1 2

4 1

2 1

4 2

2 3

4 3

3 2

2 2

17

1 3

1 4

2 2

1 5

2 4

2 3

3 1

3 2

3 5

3 4

4 2

4 3

4 4

1 6

5 3

30 30

3 3

17

1 3

1 4

2 2

1 5

2 4

2 3

3 1

3 2

3 5

3 4

4 2

3 3

4 4

1 6

5 3

4 3

100 100

答案

4 2

9 4

6 4

1 2

2 2

4 3

9 4

9 3

#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;
const int maxn = 1e4;
const int INF = 2*1e9+10;
const int dir[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
typedef pair<int, int> pii;

int N, Nw, Nb, X[maxn+5], Y[maxn+5], f[maxn+5], c[maxn+5];
map<pii, int> R;

void init () {
    scanf("%d", &N);

    Nw = N / 2;
    Nb = N - Nw;

    R.clear();
    for (int i = 0; i < N; i++) {
        f[i] = i;
        c[i] = 0;
    }
}

inline int bit (int x) {
    return x&1;
}

int getfar (int x) {
    return f[x] == x ? x : f[x] = getfar(f[x]);
}

inline bool isEmpty (int x, int y) {
    if (x <= 0 || y <= 0 || x >= INF || y >= INF)
        return false;
    if (R.count(make_pair(x, y)))
        return false;
    return true;
}

inline int count_empty (pii u) {
    int cnt = 0;
    for (int i = 0; i < 4; i++) {
        int x = u.first + dir[i][0];
        int y = u.second + dir[i][1];
        if (isEmpty(x, y))
            cnt++;
    }
    return cnt;
}

inline void link_board (int x, int y) {
    int fx = getfar(x);
    int fy = getfar(y);

    f[fy] = fx;
    c[fx] += c[fy];
    /**/
    c[fx]--;
}

int del_board (int col, int x, int y) {
    int cnt = 1;
    pii u = make_pair(x, y);
    queue<pii> que;
    que.push(u);

    f[R[u]] = R[u];
    R.erase(u);

    while (!que.empty()) {
        u = que.front();
        que.pop();

        for (int i = 0; i < 4; i++) {
            int p = u.first + dir[i][0];
            int q = u.second + dir[i][1];

            if (p <= 0 || p >= INF || q <= 0 || q >= INF)
                continue;

            pii v = make_pair(p, q);
            if (!R.count(v))
                continue;

            int set = R[v];

            if (bit(set) != col) {
                int k = getfar(set);
                c[k]++;
                continue;
            }

            f[R[v]] = R[v];
            R.erase(v);
            cnt++;
            que.push(v);
        }
    }
    return cnt;
}

 void del_empty (int k) {
    int fk = getfar(k);
    c[fk]--;

    if (c[fk] == 0) {
        int set = bit(fk);
        int cnt = del_board(set, X[fk], Y[fk]);
        if (set)
            Nw -= cnt;
        else
            Nb -= cnt;
    }
}

void solve () {

    for (int i = 0; i < N; i++) {
        scanf("%d%d", &X[i], &Y[i]);
        pii v = make_pair(X[i], Y[i]);
        c[i] = count_empty(v);
        R[v] = i;

        for (int j = 0; j < 4; j++) {
            int p = X[i] + dir[j][0];
            int q = Y[i] + dir[j][1];

            if (p <= 0 || q <= 0 || p >= INF || q >= INF)
                continue;

            pii u = make_pair(p, q);
            if (!R.count(u))
                continue;

            int k = R[u];
            if (bit(i) == bit(k))
                link_board(i, k);
            else
                del_empty(k);
        }

        int fi = getfar(i);
        if (c[fi] == 0) {
            int cnt = del_board(bit(fi), X[fi], Y[fi]);
            if (bit(fi))
                Nw -= cnt;
            else
                Nb -= cnt;
        }
    }
    printf("%d %d\n", Nb, Nw);
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        init();
        solve();
    }
    return 0;
}

hdu 4775 Infinite Go(暴力)

时间: 2024-12-14 08:04:05

hdu 4775 Infinite Go(暴力)的相关文章

HDU 4775 Infinite Go(并查集,模拟)

HDU 4775 Infinite Go 题目链接 题意:围棋,两人轮流走,如果有一链被围死,就会被吃掉,问下完后最后黑色和白色各剩多少棋 思路:模拟,利用一个并查集来保存链,然后并记录下周围有多少个空格,然后去模拟,注意几个点,就是删除的时候,要把空格还回去,还有边界的位置是也算被围死的 代码: #include <stdio.h> #include <string.h> #include <queue> #include <map> using name

HDU 4499 Cannon (暴力搜索)

题意:在n*m的方格里有t个棋子,问最多能放多少个炮且每个炮不能互相攻击(炮吃炮) 炮吃炮:在同一行或同一列且中间有一颗棋子. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

HDU 4902 线段树||暴力

给定一个序列,两种操作 1:把一段变成x. 2:把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 线段树解法:用lazy标记下即可,优化方法还是很巧妙的, Accepted 4902 515MS 3308K 1941 B C++ #include "stdio.h" #include "string.h" struct node { int l,r,x;// 在叶子节点代表值,树节点代表成端更新的lazy操作. }data[400010]

HDU 4831 Scenic Popularity 暴力模拟

Scenic Popularity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 340    Accepted Submission(s): 110 Problem Description 临近节日,度度熊们最近计划到室外游玩公园,公园内部包括了很多的旅游景点区和休息区,由于旅游景点很热门,导致景点区和休息区都聚集了很多人.所以度度熊

HDU 4961 Boring Sum 暴力

题意:对于所有的A[I],同时找到左边和右边离它最近且是它的倍数的数相乘最后加起来求和. 解题思路:n*sqrt(n)的算法,开始以为过不了,wa了两发因为lld I64d对拍一个小时发现一个小时前交的代码没错只是没变I64d,..具体思路是枚举每个a[i]的因子,找离它最近的那个更新,如果已经没更新就不用更新了.用两个辅助数组记录最近的就行. 解题代码: 1 // File Name: 1002.cpp 2 // Author: darkdream 3 // Created Time: 201

HDU - 2089 不要62 (暴力或数位DP)

Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众. 不吉利的数字为所有含有4或62的号码.例如: 62315 73418 88914 都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列. 你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新

hdu 4737 二分或暴力

http://acm.hdu.edu.cn/showproblem.php?pid=4737 Problem Description There are n numbers in a array, as a0, a1 ... , an-1, and another number m. We define a function f(i, j) = ai|ai+1|ai+2| ... | aj . Where "|" is the bit-OR operation. (i <= j)

hdu 2615 Division(暴力)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2615 题解:挺简单的暴力枚举,小小的分治主要是看没人写题解就稍微写一下 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; ll a[123] , ans , sum[123

hdu 1496 Equations (暴力+hash)

题目意思: http://acm.hdu.edu.cn/showproblem.php?pid=1496 对于方程a*x1^2+b*x2^2+c*x3^2+d*x4^2=0,给出a,b,c,d,求出有多少种方法使得方程成立,xi!=0,属于[-100,100] a,b,c,d也不为0,属于[-50,50]. Sample Input 1 2 3 -4 1 1 1 1 Sample Output 39088 0 题目分析: 直接暴力的话,会100^4,,超时,我们可以把等式转化为a*x1^2+b*