P9582 题解

题目传送门

思路

我们先看看有特殊性质的方法怎么做。有特殊性质,则一个格子的好朋友定义就变成了只要这两个方格中的数字相同,这两个方格就是好朋友。我们设 sumisum_i 为数字为 ii 的数字个数,则一个数字为 ii 的格子的好朋友数量就是 sumi1sum_i-1,因为这个格子和自己不是好朋友,而其它数字和它都是好朋友。我们只要枚举每个点,统计所有的 sumai,j1sum_{a_{i,j}}-1 之和即可。

我们再来看看无特殊性质的方法怎么做。无特殊性质的情况,我们只要在原先的基础上,再减去与当前格子相邻且与当前格子颜色相同的数量即可,即 sumai,j1(ai1,jsum_{a_{i,j}}-1-(a_{i-1,j} 是否等于 ai,j)(ai+1,ja_{i,j})-(a_{i+1,j} 是否等于 ai,j)(ai,j1a_{i,j})-(a_{i,j-1} 是否等于 ai,j)(ai,j+1a_{i,j})-(a_{i,j+1} 是否等于 ai,j)a_{i,j})

代码

# include <bits/stdc++.h>
using namespace std;
# define f(x,y) - (a[i][j] == a[x][y]) //简介一点
long long ans, n, m, a[2005][2005], sum[10], x; //记得 long long
int main () {
	cin >> n >> m;
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= m; ++ j)
			cin >> x, ++sum[a[i][j] = x];
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= m; ++ j)
			ans += sum[a[i][j]] - 1 f (i + 1, j) f(i - 1, j) f(i, j - 1) f(i, j + 1);
	cout << ans;
	return 0;
}
posted @ 2023-08-26 23:34  Vitamin_B  阅读(28)  评论(0)    收藏  举报  来源