UVa 10148

题意:

 在一个街道上有很多广告位,现在一家公司需要投放广告,要针对具体情况投放。给定一个K值,假如慢跑者经历K以上个路段,至少要看到K个广告位,经历少于等于K个,则需要让慢跑者看到全部广告位,求投放的最少的广告位。

思路:贪心+排序

   对于慢跑者经历的路段区间,按区间右端点升序排序,从区间最右端向左遍历每一个慢跑者的区间,对需要设置的广告位进行标记,最后输出标记的点。

  注意:输入数据有负值,我的办法是加上一个数,使其转换成非负数。

代码:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 #define MAXN 20000 + 10
  8 #define MAXA 1020
  9 #define PLUS 10009
 10 
 11 struct Jogger{
 12     int _start;
 13     int _end;
 14 };
 15 
 16 bool cmp(const Jogger &a,const Jogger &b){
 17     if(a._end < b._end)
 18         return true;
 19     else
 20         return false;
 21 }
 22 class Advertise{
 23     private:
 24         int adNum;
 25         int joggerNum;
 26         Jogger joggers[MAXA];
 27         int ansNum;
 28         bool isMark[MAXN];
 29     public:
 30         void init();
 31         void readData();
 32         void process();
 33         void output();
 34 };
 35 void Advertise::init(){
 36     memset(isMark,false,sizeof(isMark));
 37     adNum = 0;
 38     joggerNum = 0;
 39     ansNum = 0;
 40 }
 41 void Advertise::readData(){
 42     init();
 43     scanf("%d %d",&adNum,&joggerNum);
 44     for(int i = 0;i < joggerNum;i++) {
 45         int t1,t2;
 46         scanf("%d %d",&t1,&t2);
 47         if(t1 > t2) {
 48             joggers[i]._start = t2 + PLUS;
 49             joggers[i]._end = t1 + PLUS;
 50         }
 51         else{
 52             joggers[i]._start = t1 + PLUS;
 53             joggers[i]._end = t2 + PLUS;
 54         }
 55     }
 56 }
 57 void Advertise::process(){
 58     sort(joggers,joggers + joggerNum,cmp);
 59     for(int i = 0;i < joggerNum;i ++){//遍历每一个慢跑者
 60         if(joggers[i]._end - joggers[i]._start + 1 <= adNum){ //慢跑者跑过的广告牌数小于顾客要求的情况
 61             for(int k = joggers[i]._end;k >= joggers[i]._start;k--)//遍历慢跑者经过的广告牌
 62                 isMark[k] = true;
 63         }
 64         else{ //慢跑者跑过的广告牌数大于顾客要求的情况
 65             int markNum = adNum;
 66             for(int j = joggers[i]._start;j <= joggers[i]._end;j++){//遍历慢跑者经过的广告牌
 67                 if(isMark[j])
 68                     markNum--;
 69             }
 70             for(int j = joggers[i]._end;j >= joggers[i]._start;j--){
 71                 if(markNum <= 0)
 72                     break;
 73                 else if(!isMark[j]){
 74                     isMark[j] = true;
 75                     markNum--;
 76                 }
 77                 else continue;
 78             }
 79 
 80         }
 81     }
 82 }
 83 
 84 void Advertise::output(){
 85     for(int i = 0;i < MAXN;i++){
 86         if(isMark[i])ansNum++;
 87     }
 88     printf("%d
",ansNum);
 89     for(int i = 0;i < MAXN;i++){
 90         if(isMark[i]){
 91             printf("%d
",i - PLUS);
 92         }
 93     }
 94 }
 95 int main()
 96 {
 97 //    #ifndef ONLINE_JUDGE
 98 //        freopen("D:\acm.txt","r",stdin);
 99 //    #endif // ONLINE_JUDGE
100     Advertise adver;
101     int cases;
102     scanf("%d",&cases);
103     while(cases--){
104         adver.readData();
105         adver.process();
106         adver.output();
107         if(cases > 0)printf("
");
108     }
109     return 0;
110 }
Donghua University
原文地址:https://www.cnblogs.com/ohxiaobai/p/4493262.html