CF1774B-Coloring

挺有意思的一个思维题

题面翻译

Cirno_9baka 的纸条上有 \(n\) 个格子,他觉得空白的纸条看着有点无趣,于是想在纸条的格子上涂上 \(m\) 种颜色。同时,他认为第 \(i\) 种颜色必须要用 \(a_i\) 次,且每连续 \(k\) 个格子里涂的颜色必须互不相同。

Cirno_9baka 想知道有没有这样的一种涂色方案能符合他的要求。

Cirno_9baka has a paper tape with $ n $ cells in a row on it. As he thinks that the blank paper tape is too dull, he wants to paint these cells with $ m $ kinds of colors. For some aesthetic reasons, he thinks that the $ i $ -th color must be used exactly $ a_i $ times, and for every $ k $ consecutive cells, their colors have to be distinct.

Help Cirno_9baka to figure out if there is such a way to paint the cells.

分析

这里用到了鸽笼原理 (鸽巢原理、抽屉原理、狄利克雷原理),鸽笼原理容易理解,但是活用并不容易。

\(n\) 个元素的集合划分成 \(m\) 个集合,则其中至少有一个集合中含有大于等于 \(\left\lceil\dfrac{n}{m}\right\rceil\)

那么活用鸽笼原理,一定要记住这一点:分清楚谁是苹果谁是抽屉。

这题的抽屉便是 \(k\)\(k\) 的长度为一段,这一段内不能有重复。

那么我们可以算出段数,\(v = \left\lceil\dfrac{n}{k}\right\rceil\),这个段数上取整的意义是为了包括最后一段。即每段都是 \(k\) 段的段数加上模 \(k\) 的余数 \(r\)\(r\) 就是最后一段内的数量 \(0\le r<k\)

那么结合 \(a_i\) 考虑。

(1)如果 \(\exists a_i > v\),则无法构造出合法序列,最多只有 \(c\) 个盒子,\(a_i>v\) 意味着一定有一个盒子中的数量 \(\ge 2\),这里面蕴含了鸽笼原理的思想;

(2)如果有 \(q\)\(a_i=v\),且 \(q > r\),也无法构造出合法序列,因为这 \(q\)\(a_i\) 都是要往最后一段里加一个 \(1\) 的,所以当 \(q>r\) 时,必定有一个盒子重复。

(3)除此之外都可行。

#include <bits/stdc++.h>

inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

using namespace std;

int main()
{
	int T = read();
	int n,m,k;
	while (T--) {
		n = read(), m = read(), k = read();
		int v = int(ceil(n*1.0/k)), a, f = 0, c = 0;
        // v 的取整特别严格,只有这么写才不会挂分
		for (int i = 1; i <= m; i++) {
			a = read();
			if (a > v) f = 1;
			if (a == v) c++;
		}
		if (f == 1) printf("NO\n");
		else if (c > (n  - 1) % k + 1) printf("NO\n");
		else printf("YES\n");
	}
    return 0;
}

关注程序的第21行,(n - 1) % k + 1 这个处理很妙。如果我们写 n%k 则是值域在 \([0,k-1]\),而前者是 \([1,k]\)。我们可以写成 n%k==0?n:n%k。那么这里为什么要这么写呢?因为当 \(k|n\) 时,\(n\) 被恰好分为 \(k\) 段,那么这时就没有多余的 \(r\) 也就无需这样操作。

posted @ 2023-01-04 20:57  Vegdie  阅读(58)  评论(0编辑  收藏  举报