牛的学校
题目大意:这只Bessie真是太顽皮了,她又搞了个学校,准备招生,准备通过一个考试筛选考生,但是不能招到每个学生,每个学生也不能一定能上学,要资助,问你在一定资金内,怎么收学生,使收到的学生的平均分最高?
这一道题怎么做呢?我们知道,题目给了一个条件就是N一定是奇数,这样其实就给了我们一个套路,那就是N一定是中间的那个数,一开始我想着用一个堆去从头到尾查找,结果想了很久还是失败了。
其实这一道题要用到两个堆,分别储存左翼和右翼,我们想得到N在中间的时候左翼和右翼加起来在资金的时候的所有值,而且N必须要大(先把score排序就可以了)
这一题说实话我没想出来,不过也是给自己一个教训吧,原来堆还可以这样用。
参考:http://www.hankcs.com/program/cpp/poj-2010-moo-university-financial-aid.html
1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 #include <queue> 5 #define MAX_N 2000000001 6 7 using namespace std; 8 9 typedef int Position; 10 typedef int Heap; 11 typedef struct _set 12 { 13 int score; 14 int aid; 15 bool operator <(const _set &x)const 16 { 17 return score < x.score;//最大堆 18 } 19 }Cows; 20 int fcmop(const void *a, const void*b) 21 { 22 return (*(Cows *)b).score - (*(Cows *)a).score; 23 } 24 25 static Cows cows_set[100001]; 26 static Heap Heap_Cow[100001]; 27 static int Left[100001]; 28 static int Right[100001]; 29 30 void Insert(Position, const int); 31 int DeleteMax(int *const); 32 void Get_Left(const int, const int); 33 void Get_Right(const int, const int); 34 35 void Insert(Position pos, const int item) 36 { 37 Position s = pos, pr; 38 for (; s > 1; s = pr) 39 { 40 pr = s % 2 == 1 ? (s - 1) >> 1 : s >> 1; 41 if (Heap_Cow[pr] < item) 42 Heap_Cow[s] = Heap_Cow[pr]; 43 else break; 44 } 45 Heap_Cow[s] = item; 46 } 47 48 int DeleteMax(int *const Heap_size) 49 { 50 int max_item = Heap_Cow[1], tmp = Heap_Cow[(*Heap_size)--]; 51 Position s, s1, s2, pr = 1; 52 53 for (; pr <= *Heap_size;) 54 { 55 s1 = pr << 1; s2 = s1 + 1; 56 if (s2 <= *Heap_size) 57 { 58 s = Heap_Cow[s1] > Heap_Cow[s2] ? s1 : s2; 59 Heap_Cow[pr] = Heap_Cow[s]; 60 pr = s; 61 } 62 else if (s1 <= *Heap_size) 63 { 64 Heap_Cow[pr] = Heap_Cow[s1]; 65 pr = s1; 66 break; 67 } 68 else break; 69 } 70 Insert(pr, tmp); 71 return max_item; 72 } 73 74 void Get_Left(const int N, const int C) 75 { 76 int mid = N / 2, sum_tmp = 0, i, Heap_size = 0; 77 78 for (i = 0; i < mid; i++)//初始化 79 { 80 Left[i] = MAX_N; 81 sum_tmp += cows_set[i].aid; 82 Insert(++Heap_size, cows_set[i].aid); 83 } 84 for (; i < C; i++) 85 { 86 Left[i] = sum_tmp; 87 Insert(++Heap_size, cows_set[i].aid); 88 sum_tmp += cows_set[i].aid; 89 sum_tmp -= DeleteMax(&Heap_size);//减去最大值 90 } 91 } 92 93 void Get_Right(const int N, const int C) 94 { 95 int mid = N / 2, sum_tmp = 0, i, Heap_size = 0; 96 97 for (i = C - 1; i >= C - mid; i--)//初始化 98 { 99 Right[i] = MAX_N; 100 sum_tmp += cows_set[i].aid; 101 Insert(++Heap_size, cows_set[i].aid); 102 } 103 for (; i >= 0; i--) 104 { 105 Right[i] = sum_tmp; 106 Insert(++Heap_size, cows_set[i].aid); 107 sum_tmp += cows_set[i].aid; 108 sum_tmp -= DeleteMax(&Heap_size);//减去最大值 109 } 110 } 111 112 int main(void) 113 { 114 int N, C, F, i; 115 Cows tmp; 116 while (~scanf("%d%d%d", &N, &C, &F)) 117 { 118 for (i = 0; i < C; i++) 119 { 120 scanf("%d%d", &tmp.score, &tmp.aid); 121 cows_set[i] = tmp; 122 } 123 qsort(cows_set, C, sizeof(Cows), fcmop); 124 Get_Left(N, C); 125 Get_Right(N, C); 126 127 for (i = 0; i < C; i++) 128 { 129 if (Left[i] + Right[i] + cows_set[i].aid <= F) 130 { 131 printf("%d\n", cows_set[i].score); 132 break; 133 } 134 } 135 if (i == C) printf("-1\n"); 136 } 137 return 0; 138 }