题目大意:在一个公园里,有N个跑步者,每个跑步者都有固定的跑步范围,有个广告商要在公园里放置广告牌,要求每个广告牌至少要被每个跑步者看到K次,如果跑步者的区间不够K的要,那么在他的区间内每个点都要有广告牌
解题思路:区间选点问题,先按右端从小到大排序,然后统计该区间内已经有几个广告牌了,如果满足了就退出,如果不满足的话,就从最右端开始取点放置广告牌,具体的详解在LRJ的书上,记得判断要放置广告牌的点是否被放置了,还得从小到达排序。。。这个WA了好多次
#include<cstdio>
#include<algorithm>
#include<set>
#include<cstring>
using namespace std;
const int maxn = 20000 + 5;
struct joggers{
int x;
int y;
int count;
}jog[maxn];
int r[maxn],ans[maxn*5],cnt;
int flag[maxn];
//bool flag;
int chr = 10000;
int cmp(const void *p1,const void *p2) {
int *p = (int *)p1;
int *q = (int *)p2;
return jog[*p].y > jog[*q].y ? 1:-1;
}
int main() {
int test,K,N,M,bo = 1;
scanf("%d", &test);
while(test--) {
if(bo)
bo = 0;
else
printf("\n");
scanf("%d%d",&K,&N);
int temp;
set<int> s;
for(int i = 0; i < N; i++) {
scanf("%d%d", &jog[i].x,&jog[i].y);
r[i] = i;
if(jog[i].x > jog[i].y) {
temp = jog[i].x;
jog[i].x = jog[i].y;
jog[i].y = temp;
}
}
cnt = 0;
qsort(r,N,sizeof(r[0]),cmp);
memset(flag,0,sizeof(flag));
for(int i = 0; i < N; i++) {
int ftc = 0;
for(int j = jog[r[i]].x ; j <= jog[r[i]].y; j++)
if(flag[chr+j]) {
ftc++;
if(ftc == K)
break;
}
if(ftc == K)
continue;
for(int j = jog[r[i]].y; j >= jog[r[i]].x; j--) {
if(!flag[chr + j]) {
flag[chr+j] = 1;
ans[cnt++] = j;
ftc++;
}
if(ftc == K)
break;
}
}
sort(ans,ans+cnt);
printf("%d\n",cnt);
for(int i = 0; i < cnt; i++)
printf("%d\n", ans[i]);
}
return 0;
}