UVA10148- Advertisement(区间选点)

题意:一段路上,给出n个慢跑者跑步的区间,给出k,要求让每个慢跑者都能看到k个广告,区间都是整数操作,也就是说一个广告只能放在一个整数上,求最小贴的广告数

思路:关于区间选点的问题。把所有区间按B从小到大排序(B相同时A从大到小排序),则如果出现区间包含的情况,小区间一定排在前面。所以贪心的策略就是,从后往前取k个点。因为只有从后面开始取点,满足的区间才最会最多,这样就能达到使用最少的点的目的。注意如果区间长度小于k的话,区间内所有点都要取到。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 10000;

struct jogger{
    int A, B;
}p[MAXN];

int vis[MAXN * 2 + 5];
int k, n, cnt;

int cmp(jogger a, jogger b) {
    if (a.B != b.B)
        return a.B < b.B;
    return a.A > b.A;
}

int main() {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%d %d", &k, &n);
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &p[i].A, &p[i].B);
            p[i].A += MAXN;
            p[i].B += MAXN;
            if (p[i].A > p[i].B)
                swap(p[i].A, p[i].B);
        }

        cnt = 0;
        memset(vis, 0, sizeof(vis));
        sort(p, p + n, cmp);
        for (int i = 0; i < n; i++) {
            if (p[i].B - p[i].A <= k - 1) {
                for (int j = p[i].A; j <= p[i].B; j++)
                    if (!vis[j]) {
                        vis[j] = 1;
                        cnt++;
                    }
            }
            else {
                int temp = 0;
                for (int j = p[i].A; j <= p[i].B; j++)
                    if (vis[j])
                        temp++;
                if (temp >= k)
                    continue;
                for (int j = p[i].B; j >= p[i].A; j--) {
                    if (!vis[j]) {
                        vis[j] = 1;
                        cnt++;
                        temp++;
                    }
                    if (temp >= k)
                        break;
                }
            }
        }

        printf("%d\n", cnt);
         for (int i = 0; i < MAXN * 2 + 5; i++)
             if (vis[i] && cnt) {
                 printf("%d\n", i - MAXN);
                 cnt--;
             }
         if (cas)
             printf("\n");
    }
    return 0;
}

UVA10148- Advertisement(区间选点),布布扣,bubuko.com

时间: 2024-11-20 08:33:55

UVA10148- Advertisement(区间选点)的相关文章

【区间选点问题】uva 10148 - Advertisement

区间选点问题,即数轴上有n个闭区间[l1i, ri],取尽量少的点,使得每个区间内都至少有一个点. The Department of Recreation has decided that it must be more profitable, and it wants to sell advertising space along a popular jogging path at a local park. They have built a number of billboards (s

区间选点问题

Advertisement:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21426 经典的区间选点问题,要求每个区间内的点数满足条件k个,具体做法是把右端点从小到大排序,然后每次都检查区间内的点数,如果少了,就尽量从右边开始加点,以便于和其他区间共用一点 #include"iostream"#include"algorithm"#include"cstring"using

poj1328Radar Installation(贪心—区间选点)

题目链接: 啊哈哈,点我点我 题目: Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 52037   Accepted: 11682 Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small isl

HDU 4883 TIANKENG’s restaurant(区间选点)

HDU 4883 TIANKENG's restaurant 题目链接 题意:给定一些时间作为区间,和一个人数,问要安排多少人去看管(一个人只能看管一个人) 思路:普通的区间选点问题,一个区间拆成一个进入点一个出去点,然后排序循环求答案即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 20005; struct Man {

贪心--区间覆盖及区间选点问题

区间覆盖: 数轴上有若干区间,选用最少的线段覆盖指定区间. 区间选点:选用最少的区间使每个区间内至少有一个点 样题1: J - Muddy roads Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Farmer John has a problem: the dirt road from his farm to town has suffered in the re

UVa1615 Highway (贪心,区间选点)

链接:http://bak.vjudge.net/problem/UVA-1615 分析:以村庄为圆心,D为半径作圆,可选区间就是高速公路在圆内的部分(包括两个交点),按区间右端点从小到大,如若右端点相同再按左端点从大到小排好序,接下来就是很纯粹的区间选点问题. 1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 6 const int maxn =

UVa 1615 Highway (贪心,区间选点问题)

题意:给定一个数 n 个点,和一个d,要求在x轴上选出尽量少的点,使得对于给定的每个点,都有一个选出的点离它的欧几里德距离不超过d. 析:首先这是一个贪心的题目,并且是区间选点问题,什么是区间选点呢,就是说在数轴上有 n 个闭区间,取尽量少的点,使得每个区间都至少有一个点. 一看是不是和这个题很相似,是的,那么区间哪里来呢?自己造呗,既然说是距离不超过d,意思就是在给定的点为圆心,以 d 为半径画圆,在x轴上的区间, 那么区间不就有了么,然后这个怎么贪心呢,是这样的,把所有的区间的右端点从小到大

区间选点+区间覆盖

区间选点+区间覆盖 区间选点问题(选择最少的点,使得每个区间都至少有k个点) 将这些区间[l,r]先按照r从小到大排序,再按照l从大到小排序.选点尽量选择靠近右边界的点.然后按照这个排序后的区间进行遍历,用一个变量来存放遍历过程中上个区间的右边界,然后碰到一个新的区间的时候需要分两种情况讨论:1.这个区间和上个区间有相交的部分,那么就需要判断一下上次选择的点有多少在这个区间内,这些点满足要求吗?不满足的话还需要在这个区间内选点2.这个区间和上个区间没有交集,那么这个区间就需要选点. 上述策略可以

Poj1328--Radar Installation(区间选点)

Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64121   Accepted: 14418 Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point loca