題目原意: 在一維座標系下存在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;
}