CF1772F 题解

洛谷传送门 & CF 传送门

思路

这题有一个很重要的突破口——操作不可逆,所以可操作的次数是不上升的。所以我们可以对每张图片都统计一次可以操作的数量,然后从大到小排序就得到了打乱前的顺序。至于改变的顺序,那就只要看一下相邻两张图片有哪几个格子不一样即可。

代码

// LUOGU_RID: 119511355
# include <bits/stdc++.h>
using namespace std;
typedef pair <int, int> pii; //简写,注意不能放到 using namespace std; 前面,因为 pair 是要用到 std 的
struct node {
	string a[35];
	int tot, id;
	bool operator < (const node& x) const { //重载运算符
		return tot > x.tot;
	}
} a[105];
int n, m, k;
vector <pii> ans;
bool check (string a[], int i, int j) { //判断是否合法
	return a[i][j] != a[i + 1][j] && a[i][j] != a[i - 1][j] && a[i][j] != a[i][j + 1] && a[i][j] != a[i][j - 1];
}
int main () {
	cin >> n >> m >> k;
	++ k; //k+1 张图片
	for (int i = 1; i <= k; ++ i) {
		a[i].id = i;
		for (reg int j = 1; j <= n; ++ j) {
			cin >> a[i].a[j];
			a[i].a[j] = ' ' + a[i].a[j];
		}
		for (reg int j = 2; j < n; ++ j) //注意这部分不能和输入合并到一起!!!否则 a[j+1] 还没输入,你会 WA on #16
			for (reg int k = 2; k < m; ++ k)
				a[i].tot += check (a[i].a, j, k); //统计有几个可以被修改
	}
	sort (a + 1, a + k + 1); //排序
	for (int i = 1; i < k; ans.push_back ({a[++ i].id, 0}))
		for (int j = 2; j < n; ++ j)
			for (int k = 2; k < m; ++ k)
				if (a[i].a[j][k] != a[i + 1].a[j][k] && check (a[i].a, j, k))
					ans.push_back ({j, k});
	cout << a[1].id << '\n' << ans.size () << '\n';
	for (pii i : ans)
		if (i.second)
			cout << "1 " << i.first << ' ' << i.second << '\n';
		else
			cout << "2 " << i.first << '\n';
	return 0;
}
posted @ 2023-08-07 19:56  Vitamin_B  阅读(5)  评论(0)    收藏  举报  来源