UVa 10148 - Advertisement
题意:
在一个街道上有很多广告位,现在一家公司需要投放广告,要针对具体情况投放。给定一个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\n",ansNum); 89 for(int i = 0;i < MAXN;i++){ 90 if(isMark[i]){ 91 printf("%d\n",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("\n"); 108 } 109 return 0; 110 }
Donghua University