题意:
某条街道上有很多个广告位,一个公司在这条街上投放广告,因为不同地方的人流量是不同的,所以公司先做了个调查,共调查了N个人,知道了他们每个人每天在街上走的路段。现在要求找到一些广告位,使得广告位数量最少,但是要求调查到的那些每人至少看到广告K次。如果有人走的路段广告位少于K个,那么要求他在这个路段的所有广告位都要看到。输出要求的广告位的位置。
LRJ上的P154,将区间[ai,bi]按bi排序,然后尽量从有边开始装,如果区间长度小于K,这个区间就要全装,然后不够K个就是补足K个,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 20005;
int K,N;
bool vis[MAXN];
struct Node{
int left;
int right;
friend bool operator <(const Node &a,const Node &b){
return a.right < b.right;
}
}arr[1005];
void solve(){
sort(arr,arr+N);
memset(vis,0,sizeof(vis));
int sum = 0;
for (int i = 0; i < N; i++){
if (arr[i].right - arr[i].left + 1 <= K){
for (int j = arr[i].left; j <= arr[i].right; j++)
if (!vis[j]){
sum++;
vis[j] = true;
}
}
else {
int cnt = 0;
for (int j = arr[i].left; j <= arr[i].right; j++)
if (vis[j])
cnt++;
if (cnt >= K)
continue;
for (int j = arr[i].right; j >= arr[i].left; j--)
if (!vis[j]){
vis[j] = true;
cnt++;
sum++;
if (cnt >= K)
break;
}
}
}
printf("%d\n",sum);
for (int i = 0; i < MAXN; i++)
if (vis[i])
printf("%d\n",i-10000);
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d",&K,&N);
for (int i = 0; i < N; i++){
scanf("%d%d",&arr[i].left,&arr[i].right);
arr[i].left += 10000,arr[i].right += 10000;
if (arr[i].left > arr[i].right){
int t = arr[i].left;
arr[i].left = arr[i].right;
arr[i].right = t;
}
}
solve();
if (t)
printf("\n");
}
return 0;
}