这段代码目的是求出,对于每个位置,输出相邻的两个数中的不同的数的坐标。输入n行m列。为了简化,这里仅考虑n=1。
(因为1行元素的时候就挂了)
我的思路:用set存不相等的位置的哈希值。
不要问我为什么这个思路,因为实现这个功能是完整题目的一部分。
输入
1 4
2 1 2 4
理论上应输出:
1 1:(1 2)
1 2:(1 3) (1 1)
1 3:(1 2) (1 4)
1 4:(1 3)
不要在意坐标的逗号在哪
结果,我的输出
1 1:(1 2)
1 2:(1 1)
1 3:(1 2) (1 4)
1 4:(1 3)
然后我发现只要把输入改成
1 4
2 1 3 4
就对了。需要让第三个数不等于第一个数。
甚至输入
1 4
1 2 1 2
输出是:
1 1:(1 2)
1 2:(1 1)
1 3:(1 2)
1 4:(1 3)
这是为什么呢qwq
#include <bits/stdc++.h>
using namespace std;
int n, m;
#define px(p) ((p - 1) / m + 1)
#define py(p) ((p - 1) % m + 1)
#define pp(x, y) ((x - 1) * m + y)
const int N = 200005;
int c[N], fa[N];
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
struct cmp {
bool operator() (int a, int b) {
return c[find(a)] < c[find(b)];
}
};
set <int, cmp> ad[N]; // ad[x] 联通块的代表x,所相邻的所有连通块代表
void pri() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int f = find(pp(i, j));
cout << "(" << px(f) << "," << py(f) << ") ";
}
cout << "\n";
}
}
//
//void print() {
// for (int i = 1; i <= n; i++) {
// for (int j = 1; j <= m; j++) {
// int f = find(pp(i, j));
// cout << c[f] << " ";
// }
// cout << "\n";
// }
//}
//
void print2(int x) {
cout << px(x) << " " << py(x) << ":";
auto it = ad[x].begin();
while (it != ad[x].end()) {
cout << "("<<px(*it) << " "<<py(*it)<<") ";
it++;
}
cout << "\n";
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n * m; i++) fa[i] = i;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int k = pp(i, j), k1 = find(pp(i - 1, j)), k2 = find(pp(i, j - 1));
cin >> c[k];
if (i > 1) {
if (c[k] != c[k1]) {
ad[k1].insert(k);
ad[k].insert(k1);
}// else merge(k, k1);
}
if (j > 1) {
if (c[k] != c[k2]) {
cout << px(k) << " " << py(k) << ":" <<
"(" << px(k2) << "," << py(k2) << ") ";
ad[k2].insert(k);
ad[k].insert(k2);
//if (px(k2))
} //else merge(k, k2);
}
}
}
//pri();
cout << "\n";
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
print2(pp(i, j));
}
return 0;
}