zoukankan      html  css  js  c++  java
  • 1416 两点 并查集

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1416

    对于每一个坐标(x, y)

    要使得它变成一个整数,一个方法就是x * max(n, m) + y

    这样就不会相同了。可以幻想一下吧。

    这样坐标的大小只会去到n * m + y这个级别,不会很大。

    然后并查集那里,每一次都走下面和右边的点,看看能否合并,能的话就合并。然后

    合并到相同的爸爸,就是有了。

    AA

    AA

    其中(4, 4)这个点被(1, 2)合并了一次,爸爸是(1, 1)

    然后又被(2, 1)合并一次,爸爸是相同了。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    const int maxn = 50 + 20;
    int fa[maxn * maxn * maxn];
    char str[maxn][maxn];
    int tofind(int u) {
        if (fa[u] == u) return fa[u];
        else return fa[u] = tofind(fa[u]);
    }
    bool tomerge(int x, int y) {
        x = tofind(x);
        y = tofind(y);
        if (x == y) return false;
        fa[y] = x;
        return true;
    }
    int n, m;
    int calc(int x, int y) {
        return max(n, m) * x + y;
    }
    void work() {
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) cin >> str[i] + 1;
        for (int i = 1; i <= maxn * maxn * maxn - 1; ++i) fa[i] = i;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (j + 1 <= m && str[i][j] == str[i][j + 1]) {
                    if (!tomerge(calc(i, j), calc(i, j + 1))) {
    //                    cout << i << endl;
    //                    cout << j << endl;
                        cout << "YES" << endl;
                        return;
                    }
                }
                if (i + 1 <= n && str[i][j] == str[i + 1][j]) {
                    if (!tomerge(calc(i, j), calc(i + 1, j))) {
                        cout << "YES" << endl;
                        return;
                    }
                }
            }
        }
        cout << "NO" << endl;
    }
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    算法训练(大富翁)
    算法训练题(奖励最小)
    算法训练题
    乔布斯
    算法题(符合题意的6位数)
    算法题(八皇后)
    算法题(分小组)
    汉诺塔
    递归算法题(兔子)
    字符串-mask-每个元音包含偶数次的最长子字符串
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6382079.html
Copyright © 2011-2022 走看看