(思维题还是太超标了,建议削一削)
a,b为t在s中左上角坐标,一一对比即可(大胆点数据量比较小,直接四层循环也能做,但是我是胆小鬼)
#include<iostream>
using namespace std;
char a[10000][10000];
char b[10000][10000];
int n, m;
void find(int i, int j) {for (int p = 1; p <= m; p++) {for (int q= 1; q <= m; q++) {if (a[i + p - 1][j + q - 1] != b[p][q]) return;}}cout << i << " " << j;return;
}
int main() {cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> a[i][j];}}for (int i = 1; i <= m; i++) {for (int j = 1; j <= m; j++) {cin >> b[i][j];}}for (int i = 1; i <= n-m+1; i++) {for (int j = 1; j <= n-m+1; j++) {if (a[i][j] == b[1][1])find(i, j);}}return 0;
}
(不会,学长的思路)
把有朋友关系的人连上边,一个连通块内的所有人都可以通过若干次操作来互相成为朋友。求出每个连通块的大小,人数和已有的朋友关系,就可以求出连通块内未有的朋友关系,也就是答案。这个过程可以用并查集维护
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n, m;
const int pp = 100000;
int sz[pp], lsz[pp], f[pp];
bool vis[pp];
long long ans = 0;
int find(int x) {if (x == f[x]) return x;return f[x] = find(f[x]);
}
int main() {for (int i = 0; i < pp; i++) {sz[i] = 0;lsz[i] = 1;f[i] = i;}cin >> n >> m;for (int i = 1; i <= m; i++) {int x, y;cin >> x >> y;int xx = find(x);int yy = find(y);if (xx == yy) {sz[xx]++;}else {f[xx] = yy;lsz[yy] += lsz[xx];sz[yy] = sz[yy] + sz[xx] + 1;}}for (int i = 1; i <= n; i++) {int fx = find(i);if (vis[fx]) continue;vis[fx] = true;ans += (long long)lsz[fx] * (lsz[fx] - 1) / 2 - sz[fx];}cout << ans;return 0;
}
(ok准备下播)