题意:一个广告商要投放广告,要求每个慢跑的人都能看到k次他的广告。然后给出N个慢跑的人的区间,求最小广告投放次数。如果一个人太胖了,跑不动,根本看不到k次广告,那么就要让这个人跑多少看多少。(为什么我想到了脑白金。。。)
思路:要想让投放的广告牌最少,又要满足每个人看的欲望,所以要尽量让一个广告牌给多个人看到。
因此就要排序,然后从跑步的终点开始往前放广告牌,直到广告牌达到k个,这样就能确保后面的人也“说不定”能看到广告牌。
其实画几个图也可以出来。
大家将就着看吧。。。。
第一幅图明显是从后面往前方放,第二幅图明显是从后面往前放,第三幅图明显是从后面往前放。。。
但是我在后面遇到问题了。。。怎么判断之前已经存在的点。。。
然后我就可耻地参考了hcbbt的解题报告。
原来开一个数组就可以了。都是些以前的知识,就是贯穿不起来。
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 10000;
struct POINT
{
int left, right;
friend bool operator < (const POINT &a, const POINT &b)
{
return a.right < b.right;
}
}point[1100];
int HashValue[MAXN * 2 + 100];
int main()
{
//freopen("input.txt", "r", stdin);
int T, i, j, n, k, a, b, ans;
scanf("%d", &T);
while (T--)
{
ans = 0;
memset(HashValue, 0, sizeof(HashValue));
scanf("%d%d", &k, &n);
for (i = 0; i < n; i++)
{
scanf("%d%d", &a, &b);
point[i].left = min(a, b);
point[i].right = max(a, b);
}
sort(point, point + n);
for (i = 0; i < n; i++)
{
int cnt = 0;
for (j = point[i].left; j <= point[i].right; j++)
if (HashValue[j + MAXN])
cnt++;
for (j = point[i].right; j >= point[i].left && cnt < k; j--)
{
if (!HashValue[j + MAXN])
HashValue[j + MAXN] = 1, ans++, cnt++;
}
}
printf("%d\n", ans);
for (i = 0; i < MAXN * 2 + 100; i++)
if (HashValue[i])
printf("%d\n", i - MAXN);
if (T)
printf("\n");
}
return 0;
}