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)合并一次,爸爸是相同了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }