Evanyou Blog 彩带

[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;
}
posted @ 2020-01-17 10:36  御·Dragon  阅读(247)  评论(0编辑  收藏  举报



Contact with me