【CF1774B】Coloring(构造,贪心)

【题目描述】
纸条上有 n n n个格子,在这些格子上涂上 m m m种颜色,第 i i i种颜色必须要用 a i a_i ai次,且需要满足每连续 k k k个格子里涂的颜色互不相同。请问有没有这样的一种涂色方案能符合该要求?

【输入格式】
第一行一个整数 t ( 1 ≤ t ≤ 1 0 4 ) t(1\le t\le 10^4) t(1t104),表示测试样例的数量。
对于每组测试样例第一行输入三个整数 n , m , k ( 1 ≤ k ≤ n ≤ 1 0 9 , 1 ≤ m ≤ 1 0 5 , m ≤ n ) n,m,k(1\le k\le n\le 10^9,1\le m\le 10^5,m\le n) n,m,k(1kn109,1m105,mn)
第二行输入 m m m个整数 a 1 , a 2 , … , a m ( 1 ≤ a i ≤ n ) a_1,a_2,\dots ,a_m(1\le a_i\le n) a1,a2,,am(1ain),保证 a 1 + a 2 + ⋯ + a m = n a_1+a_2+\dots +a_m=n a1+a2++am=n
数据保证每组测试用例中的 m m m的和不超过 1 0 5 10^5 105

【输出格式】
对于每组测试用例,如果有至少一种涂色的方案,输出YES;否则输出NO

【输入样例】

2
12 6 2
1 1 1 1 1 7
12 6 2
2 2 2 2 2 2

【输出样例】

NO
YES

【分析】


我们可以把序列分为 ⌈ n / k ⌉ \lceil n/k\rceil n/k个连续区间,其中除了最后一个区间外所有区间的长度均为 k k k,如果 n % k = 0 n\% k=0 n%k=0,那么最后一个区间的长度为 k k k,否则为 n % k n\% k n%k

只要满足以下条件即可构造出符合条件的涂色方案:

  • 对于所有的 a i a_i ai均满足 a i ≤ ⌈ n / k ⌉ a_i\le \lceil n/k\rceil ain/k
  • a i = ⌈ n / k ⌉ a_i= \lceil n/k\rceil ai=n/k的颜色种类数量 c n t cnt cnt小于等于最后一个区间的长度。

首先先将所有满足 a i = ⌈ n / k ⌉ a_i= \lceil n/k\rceil ai=n/k的颜色涂到每个区间的第 j ( j ∈ [ 1 , c n t ] ) j(j\in [1,cnt]) j(j[1,cnt])个位置上;然后将满足 a i < ⌈ n / k ⌉ − 1 a_i< \lceil n/k\rceil -1 ai<n/k1的颜色按循环顺序依次涂到每个区间的第 j ( j ∈ [ c n t + 1 , … , c n t + w ] ) j(j\in [cnt+1,\dots ,cnt+w]) j(j[cnt+1,,cnt+w])个位置上,即先涂到第一个区间的位置 j j j上,再涂到第二个区间的位置 j j j上,循环完所有区间后再涂到第一个区间的位置 j + 1 j+1 j+1上;最后将满足 a i = ⌈ n / k ⌉ − 1 a_i= \lceil n/k\rceil -1 ai=n/k1的颜色按循环顺序依次涂到每个区间的第 j ( j ∈ [ c n t + w + 1 , … , k ] ) j(j\in [cnt+w+1,\dots ,k]) j(j[cnt+w+1,,k])个位置上。


【代码】

#include 
#include 
#include 
#include 
using namespace std;

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n, m, k;
        cin >> n >> m >> k;
        int seg_cnt = ceil((double)n / k);  // 区间数量
        int last_len = n % k ? n % k : k;  // 最后一段区间的长度
        bool flag = true;
        int x, cnt = 0;  // cnt表示数量与区间数量相同的颜色的数量
        for (int i = 0; i < m; i++)
        {
            cin >> x;
            if (x > seg_cnt || (x == seg_cnt && ++cnt > last_len)) flag = false;
        }
        flag ? puts("YES") : puts("NO");
    }
    return 0;
}

你可能感兴趣的:(CodeForces,算法,c++,数据结构)