B. Coloring【Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!)】

题目

B. Coloring

做法

首先,我们可以将 n n n个格子分成 ⌈ n k ⌉ ⌈\frac{n}{k}⌉ kn段 ,除了最后一段外,所有段的长度都为 k k k。然后,根据题意,要求在每段中,每个格子的颜色互不相同。很容易发现任何 a i a_{i} ai应小于或等于 ⌈ n k ⌉ ⌈\frac{n}{k}⌉ kn
例如:
n n n m m m k k k
13 13 13 6 6 6 3 3 3
A A A B B B C C C D D D E E E F F F
1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 5 5 5
13 13 13个格子分成 ⌈ 13 3 ⌉ = 5 ⌈\frac{13}{3}⌉=5 313=5段,除了最后一段外,所有段的长度都为 3 3 3。然后在每段中,每个格子的颜色互不相同:
A A A E E E F F F
B B B E E E F F F
C C C E E E F F F
D D D E E E F F F
F F F
很容易发现 a i a_{i} ai应小于或等于 5 5 5,这样每一段最多可以放一种颜色,最多放5种。
然后我们可以计算等于 ⌈ n k ⌉ ⌈\frac{n}{k}⌉ kn a i a_{i} ai的数量。此数字必须小于或等于 n n n m o d mod mod k k k,即最后一段的长度。
原因是,等于 ⌈ n k ⌉ ⌈\frac{n}{k}⌉ kn a i a_{i} ai一定要放在最后一段才能放得下,那么这样的 a i a_{i} ai的数量不能大于最后一段的长度,这样的话,所有这样的 a i a_{i} ai才能放得下。
满足上述条件的所有 a a a均有效。我们可以使用以下方法构造着色:
首先,我们挑选所有满足 a i = ⌈ n k ⌉ a_{i}=⌈\frac{n}{k}⌉ ai=kn的颜色 i i i,然后我们使用颜色 i i i为每个片段中的第 j j j个单元格着色。
然后我们挑选所有满足 a i < ⌈ n k ⌉ − 1 a_{i}<⌈\frac{n}{k}⌉-1 ai<kn1的颜色 i i i,并使用这些颜色以循环顺序对其余单元格着色(即:将颜色染上第一段的第 j j j个单元格,第二段的第 j j j个单元格,…,第 ⌈ n k ⌉ ⌈\frac{n}{k}⌉ kn段的第 j j j个单元格,然后让 j + 1 j+1 j+1。当一种颜色用完时,我们开始使用下一种颜色)
最后,我们挑选所有满足 a i = ⌈ n k ⌉ − 1 a_{i}=⌈\frac{n}{k}⌉-1 ai=kn1的颜色,并用循环顺序对它们进行着色。
此方法将始终给出有效的构造。
例如:
n n n m m m k k k
13 13 13 6 6 6 3 3 3
A A A B B B C C C D D D E E E F F F
1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 5 5 5
A A A E E E F F F
B B B E E E F F F
C C C E E E F F F
D D D E E E F F F
F F F

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e5+5;
ll t,n,m,x,y,k;
ll a[maxn];
int main()
{
	cin>>t;
	while(t--){
		cin>>n>>m>>k;
		ll maxx=-1e18;
		for(int i=1;i<=m;i++)cin>>a[i];
		bool flag=true;
		for(int i=1;i<=m;i++){
			if(a[i]>ceil(n*1.0/k))flag=false;
		}
		ll cnt=0;
		for(int i=1;i<=m;i++){
			if(a[i]==ceil(n*1.0/k))cnt++;
		}
		if(flag==true&&cnt<=(n%k))puts("YES");
		else if(flag==true&&(n%k==0)&&cnt<=k)puts("YES");
		else puts("NO");
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keguaiguai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值