题意:在一条街道上,一家广告公司要安置广告牌,每天早上有m个人晨跑,需要让每个人在他跑步的区间内至少看到k个广告牌,每个整数位置可以放置一个广告牌,广告公司为了节省要求得出最少数量的广告牌和他们的位置。
题解:先按区间右边界从小到大排序,然后开始判断这个人的运动区间内是否已经安置广告牌数量不足k个,如果是就从右边界开始向左判断使广告牌数量达到k,注意每个坐标需要扩大10000,因为vis[]数组下标要大于等于0。
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1005;
int vis[50000], ans[N];
struct P {
int l, r;
}p[N];
int cmp(P a, P b) {
if (a.r != b.r)
return a.r < b.r;
else
return a.l > b.l;
}
int main() {
int t, a, b, m, n, k;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &k, &m);
memset(vis, 0, sizeof(vis));
int minn = 0;
for (int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
p[i].l = (a < b ? a : b) + 10000;
p[i].r = (a > b ? a : b) + 10000;
}
sort(p, p + m, cmp);
for (int i = 0; i < m; i++) {
int sum = 0;
for (int j = p[i].l; j <= p[i].r; j++)
if (vis[j])
sum++;
int temp1 = k - sum;
if (temp1 > 0) {
for (int j = p[i].r; j >= p[i].l && temp1; j--) {
if (!vis[j]) {
temp1--;
vis[j] = 1;
ans[minn++] = j;
}
}
}
}
sort(ans, ans + minn);
printf("%d\n", minn);
for (int i = 0; i < minn; i++)
printf("%d\n", ans[i] - 10000);
if (t)
printf("\n");
}
}