首页 > 其他分享 >CF1720E Misha and Paintings 题解

CF1720E Misha and Paintings 题解

时间:2022-09-20 21:00:27浏览次数:88  
标签:CF1720E cnt 颜色 覆盖 题解 Misha 正方形 MAXN 边长

神仙 2700。

首先统计出原数组中不同元素个数记作 \(cnt\),如果 \(cnt\le k\) 说明元素个数不够,由于一次只能加一个颜色因此答案就是 \(k-cnt\)。

然后接下来要证明一个结论:答案上限为 2。

证明:

下面都已左上角为 \((1,1)\) 为条件证明,对于左上角不为 \((1,1)\) 的情况证明类似。

考虑每次以左上角 \((1,1)\) 为正方形顶点,边长一步步扩大,如下图(绿色部分):

image

设正方形右下角 \((i,i)\),那么我们从 \((i+1,i+1)\) 开始,每次往上往左覆盖一个(但是不与之前的正方形重合),如下图(蓝色部分,黑色部分为重叠):

image

这就是两次覆盖,下面钦定这两次覆盖都使用剩余白色部分中没有的颜色覆盖。

注意到第一次覆盖之后,如果白色部分颜色种类为 \(k\) 或者是 \(k-1\),那么我们可以使绿色部分颜色覆盖为原来就有的颜色(对应 \(k\))或是一种新颜色(对应 \(k-1\)),此时答案为 1。该条件也是答案为 1 的充要条件。

如果白色部分颜色种类大于 \(k\),我们需要第二次覆盖,注意到第二次覆盖从 \(1\times1\to2\times2\to...\) 时,每次扩展两格,则颜色可能减少 0,1,2。

由于我们需要第二次覆盖,因此蓝色+白色部分原颜色种类个数一定大于 \(k\),因此我们可以证明过程中一定会有一组满足条件的绿色蓝色矩形覆盖方案,使得白色部分为 \(k\) 或者 \(k-1\),若为 \(k\) 那么就覆上两个相同且有的颜色,若为 \(k-1\) 那么一个覆有的一个覆没有的,特别的有人会问能不能 \(k-2\) 然后覆盖两个新的,但该情况其实可以归约到 \(k\) 和 \(k-1\) 的情况。

如果白色部分颜色种类小于 \(k-1\),此时我们需要缩短正方形边长,因为正常情况下你已经没法做到再覆盖一次使得颜色种类为 \(k\),最好情况就是类似于白色新覆盖一个,白色里面新覆盖一个可以做到两次,然而缩短边长同样可以两次:

考虑一种临界情况,边长为 \(i\) 时白色部分颜色种类小于 \(k-1\),边长为 \(i-1\) 时白色部分颜色种类 \(>k\)(等于 \(k\) 或 \(k-1\) 时答案就是 1,上面已经证明),然后我们使用蓝色矩形尽可能覆盖边长为 \(i-1\) 的正方形,那么只会剩下左下角右上角两个格子没有覆盖。

如果左上角右下角的颜色绿蓝色矩形里面都有,那么我们就缩短蓝色矩形边长,然后因为该情况满足正方形边长为 \(i\) 和 \(i-1\) 时小于 \(k-1\) 和大于 \(k\),因此蓝色矩形覆盖过程中就会出现白色部分为 \(k\) 或者 \(k-1\) 的情况。

上述除了证明白色部分颜色种类小于 \(k-1\) 缩短边长就可以之外,同时也证明了必然存在方案。

这样就证明了结论:答案上界为 2。

现在只需要考虑答案为 1 的情况(答案为 0 已经在 \(cnt\le k\) 中处理了),满足该情况就需要存在一个正方形满足其余部分颜色个数为 \(k\) 或 \(k-1\),考虑先枚举长度 \(len\),预处理 \(sum_{i,j}\) 表示长度为 \(len\) 时 \((i,j)\) 为左上角的正方形内完全包含多少种颜色,也就是 \(cnt-sum_{i,j}\) 为其余部分颜色个数。

为做到这一点,考虑预处理覆盖每个颜色的最小矩形 \((x1,y1),(x2,y2)\),由于枚举长度为 \(len\),我们可以知道对于每个颜色,有哪些正方形能覆盖到这个颜色,对这些正方形左上角顶点加一,即矩形加 1,这可以二维差分然后二位前缀和解决。

处理完 \(sum_{i,j}\) 后,只需要知道有无 \(cnt-sum_{i,j}\) 为 \(k\) 或 \(k-1\) 即可。

GitHub:CodeBase-of-Plozia

Code:

/*
========= Plozia =========
	Author:Plozia
	Problem:CF1720E Misha and Paintings
	Date:2022/9/20
========= Plozia =========
*/

#include <bits/stdc++.h>
typedef long long LL;

const int MAXN = 500 + 5;
int n, k, a[MAXN][MAXN], sum[MAXN][MAXN], cnt, fir[MAXN * MAXN][2], sec[MAXN * MAXN][2];
bool book[MAXN * MAXN];

int Read()
{
	int sum = 0, fh = 1; char ch = getchar();
	for (; ch < '0' || ch > '9'; ch = getchar()) fh -= (ch == '-') << 1;
	for (; ch >= '0' && ch <= '9'; ch = getchar()) sum = (sum << 3) + (sum << 1) + (ch ^ 48);
	return sum * fh;
}

int main()
{
	n = Read(), k = Read();
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			book[a[i][j] = Read()] = 1;
	for (int i = 1; i <= n * n; ++i) cnt += book[i];
	if (cnt <= k) { printf("%d\n", k - cnt); return 0; }
	memset(fir, 0x7f, sizeof(fir));
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
		{
			fir[a[i][j]][0] = std::min(fir[a[i][j]][0], i);
			fir[a[i][j]][1] = std::min(fir[a[i][j]][1], j);
			sec[a[i][j]][0] = std::max(sec[a[i][j]][0], i);
			sec[a[i][j]][1] = std::max(sec[a[i][j]][1], j);
		}
	int flag = 0;
	for (int len = 1; len <= n; ++len)
	{
		for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) sum[i][j] = 0;
		for (int i = 1; i <= n * n; ++i)
		{
			if (!book[i]) continue ;
			if (len < std::max(sec[i][0] - fir[i][0], sec[i][1] - fir[i][1])) continue ;
			int Line = sec[i][0] - fir[i][0] + 1, Col = sec[i][1] - fir[i][1] + 1;
			int r1 = std::max(1, fir[i][0] - (len - Line)), c1 = std::max(1, fir[i][1] - (len - Col));
			int r2 = std::min(n - len + 1, fir[i][0]), c2 = std::min(n - len + 1, fir[i][1]);
			++sum[r1][c1]; --sum[r2 + 1][c1]; --sum[r1][c2 + 1]; ++sum[r2 + 1][c2 + 1];
		}
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				sum[i][j] = sum[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				if (cnt - sum[i][j] == k || cnt - sum[i][j] == k - 1) flag = 1;
	}
	if (flag == 1) printf("1\n");
	else printf("2\n");
	return 0;
}

标签:CF1720E,cnt,颜色,覆盖,题解,Misha,正方形,MAXN,边长
From: https://www.cnblogs.com/Plozia/p/16712519.html

相关文章

  • Codeforces Round #821(Div.2) (A-C) 题解
    CodeforcesRound#821(Div.2)(A-C)  A.ConsecutiveSum大致题意给定一组共n个数据,如果俩个数的下标在modk意义下同余,则可以交换a[I]和a[j] ,求操作后一段......
  • Luogu T273083 新的题目 题解
    怕放洛谷有人看,就搬过来了。本题解提供一个\(O(qn)\)的做法(实际上是暴力的优化)。先考虑暴力求解。对于每个操作,要求代价\(W\times(\sum_{i\inX}^{i}w[i]\times......
  • CF1363F题解
    好妙的dp-1的情况就是字母构成的可重集不同我们将一次操作抽象成将一个字符向前移动若干格我们设f[i][j]表示s串到了第i个字母,t串到了第j个字母的最小操作次数1.将第i......
  • Codeforces #821 Div2(A~D2)题解
    CF#821Div2AConsecutiveSum题目:​ 选择\(i\)和\(j\),如果\(j=i+xk(x=R)\),可以交换\(i,j\)。任意选择一段长度为k的相加。思路:​ 题目等价于在下标\(mod\)k相同......
  • CGR1 简要题解
    G.Tree-Tac-Toe瞎扯:首先一看黑就不可能赢,最多争个平。若有度数大于\(3\)的点白直接赢了。若一个点度数为\(3\),且只有不多于\(1\)端是叶子,白也赢了。所以现在树的形......
  • js精度计算问题解决,Jsutil库源码
    为什么会存在浮点数计算精度丢失问题,这个原因不再过多赘述; JS中如何解决精度计算问题,大不部分人都知道升幂再降幂的解决方案; 但是如果直接升幂也会出现精度问题,且需......
  • sb课件的题解(复习)
    sb课件的题解(复习)不理解,为什么一个新的课件我就2题没做过,没救了CF1310C这题,我们发现它不同的子段共有\(n*(n-1)/2\)个,将其按字典序排序我们需要便捷的比较,考虑维护\(......
  • 【题解】CF1733E - Conveyor
    因为每秒只放一个球,所以对于每一个\(x+y=a\)的对角线最多只有一个球且任意两个球不会相遇,所以我们只用知道第\(t-x-y\)秒放的球的移动路径即可。等价于需要求出前\(......
  • CF round 812 div2 A-D 题解
    首先第一题TravelingSalesManProblem,给出一些坐标,就是问从原点出发,然后收集所有的点,问最少需要多少次移动这个就是求收集完那曼哈顿距离,这个距离稍加观察可以发现,就是......
  • EFCore 6级联删除问题解决Database operation expected to affect 1 row(s) but actua
    异常信息:Databaseoperationexpectedtoaffect1row(s)butactuallyaffected0row(s).Datamayhavebeenmodifiedordeletedsinceentitieswereloaded.See......