[USACO08MAR]珍珠配对Pearl Pairing 题解

洛谷题面

这题有点像脑筋急转弯,想通了就很简单

题目大意:

\(N\) 个元素(\(N\) 为偶数),需要你来染色。现在需要两个元素为一组,且每一组的元素颜色要保证不同,求任意一种解法。

题意分析:

其实我们来看看,为了保证有解,即有一种方案使得 两个元素为一组,且每一组的元素颜色要保证不同 ,所以 不可能有某种珍珠会超过总数的一半 (否则根据小奥,一定会有两个相同颜色的元素在一组)。

且我们知道: 一共有 \(N\) / 2 组

这个就是抽屉问题(鸟巢问题),想明白了就很简单。

具体操作:

题目给的是每种颜色的数量,我们不妨将 每种颜色的元素数量 转化为 每个元素的颜色。

根据小奥,我们一般做抽屉问题时都是按照 将每种颜色的珍珠按照每组一个 的方式操作。

然后为了正解,我们可以先按照 每种颜色的元素数量 从大到小排序,那么由于不可能有某种珍珠会超过总数的一半,所以即便元素数量最多的颜色的那些元素,排完序后也不可能有一个元素超过中点。

故我们不妨将 第 \(i\) 个元素与 第 \(i + (n / 2)\) 个元素合成一组,这样可以方便而快速的避免无解。

数据太水,不排序也能过,博主太懒,也把排序略了。

AC代码在此镇楼:

#include<bits/stdc++.h>
#include<cctype>
#pragma GCC optimize(2)
#define in(n) n = read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n')
#define Min(a,b) a < b ? a : b
#define Max(a,b) a > b ? a : b
#define ll long long
#define New ll
#define rg register
using namespace std;

namespace IO_Optimization
{
    inline New read()//快读 
    {
        New X = 0,w = 0;
        char ch = 0;

        while(!isdigit(ch))
        {
            w |= ch == '-';
            ch=getchar();
        }
        while(isdigit(ch))
        {
            X = (X << 3) + (X << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -X : X;
    }

    inline void write(long long x)//快输 
    {
         if(x < 0) putchar('-'),x = -x;
         if(x > 9) write(x / 10);
         putchar(x % 10 + '0');
    }
}
using namespace IO_Optimization;

const int MAXN = 100000 + 2;//定义常量 

int s[MAXN]; //记录每个珍珠的颜色 
int n,c,k;//如题,k为输入时当前有了多少珍珠数量 

int main()
{
    in(n),in(c);//输入 
    for(rg int i = 1;i <= c; ++i)
    {//枚举 
        int x = read();//输入每种颜色的数量 
        for(rg int j = 1;j <= x; ++j)//保存每个珍珠的颜色  
            s[++k] = i;//每次k加1,s[k] = i即可
    }
    n >>= 1;//N /= 2 
    for(rg int i = 1;i <= n; ++i)//截半枚举 
        out(s[i]),cout<<" ",outn(s[i + n]);//截半输出 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/CJYBlog/p/12204610.html