[NOIP模拟赛]点染色问题

题目描述

给定平面上的n个整点(xi, yi),相互不重叠。要求将每个点染成红色或者蓝色,使得每行或者每列的红色点数和蓝色点数之差小于或等于1。


输入格式

第1行:1个整数n, 表示整点的数量接下来n(1≤n≤2*10^5)行,每行2个整数xi, yi(1≤x,y≤2*10^5)


输出格式

第1行:输出一个长度为n的字符串,仅包含'r'(红色)或者'b'(蓝色),第i个字符表示第i个点所染的颜色


输入样例
3
1 1
1 2

2 1


输出样例(special judge)

brr



题解:

一列中的x个点连⌊x/2⌋条边,一行中的y点连⌊y/2⌋边,然后交叉染色。说的可能不是很清楚,详见代码。

#include<cstring>
#include<cstdio>
const int N=200010;

int n, x, y, con[2][N], can[N];
char col[2]={ 'r', 'b' };

int fir[N], ecnt;
struct node{ int e, next; } edge[N<<1];
void Link( int s, int e ) {
	edge[++ecnt].e=e; edge[ecnt].next=fir[s]; fir[s]=ecnt;
	edge[++ecnt].e=s; edge[ecnt].next=fir[e]; fir[e]=ecnt;
}

void DFS( int s ) {
	for( int i=fir[s]; i; i=edge[i].next )
		if( can[ edge[i].e ]==-1 ) {
			can[ edge[i].e ]=can[s]^1;
			DFS( edge[i].e );
		}
}

int main() {
	scanf( "%d", &n );
	for( int i=1; i<=n; i++ ) {
		scanf( "%d%d", &x, &y );
		if( con[0][x] ) Link( con[0][x], i ), con[0][x]=0;
		else con[0][x]=i;
		if( con[1][y] ) Link( con[1][y], i ), con[1][y]=0;
		else con[1][y]=i;
	}
	
	memset( can, -1, sizeof can );
	for( int i=1; i<=n; i++ )
		if( can[i]==-1 ) can[i]=0, DFS(i);
	for( int i=1; i<=n; i++ )
		printf( "%c", col[ can[i] ] );
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值