题目原意: 在一维坐标系下存在n(n>=1&&n<=100)个独一无二的点和m(m>=1&&m<=100)条的线段,且第i个点的坐标xi(xi>=0&&xi<=100),第j条线段的由[Li,Ri]表示。现在对这n个点进行涂色,每个点要么是红色,要么是蓝色,且现在要求每个线段包含这样的点的红色的个数和蓝色的个数之差的绝对值不超过1.(Li>=0&&Li<=Ri&&Ri<=100),问每个点的颜色,并输出。(方案数 有多个,只要输出其中的一个即可,蓝为1,红 0)
解题思路: 每条线段的所含有的红和蓝的个数之差的绝对值要小于1,所以我们是否可以先将所有的点按X从小到大排序,然后根据要求我们是否可以根据题目要求,且下标(点用结构体保存)为奇数的为1,偶数的为0,所以这样无论一条线段有多少个点他都保证存在奇数下标于偶数下标之差绝对值相差1,所以保证了红与蓝的个数相差1.然后再根据初始的id 再给点进行排序,即可求解。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 110
int l[MAXN],r[MAXN],ans[MAXN],bl[MAXN],re[MAXN];
typedef struct node {
int x,id;
int flag;
friend bool operator <(node aa,node bb){
return aa.x<bb.x;
}
};
node X[MAXN];
int n,m;
bool solve(int n,int m){
memset(bl,0,sizeof(bl));
memset(re,0,sizeof(re));
sort(X,X+n);
for(int i=0;i<n;++i){
X[i].flag = i%2;
}
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
if(l[i]<=X[j].x&&X[j].x<=r[i]){
if(X[j].flag==1){
bl[i]++;
}
else {
re[i]++;
}
}
}
int tmp = bl[i] - re[i];
if(tmp>=-1&&tmp<=1)continue;
return false;
}
return true;
}
int cmp2(node aa,node bb){
return aa.id<bb.id;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=0;i<n;++i){
scanf("%d",&X[i].x);
X[i].id = i;
}
for(int i=0;i<m;++i){
scanf("%d%d",&l[i],&r[i]);
}
if(!solve(n,m))
printf("-1\n");
else{
sort(X,X+n,cmp2);
printf("%d",X[0].flag);
for(int i=1;i<n;++i){
printf(" %d",X[i].flag);
}
printf("\n");
}
}
return 0;
}