[关闭]
@xingxing 2017-05-29T06:43:53.000000Z 字数 3380 阅读 850

专题三(花式STL)

题解花式STL


[题目][A]
Moo University - Financial Aid
题目大意:

解题思路:

    解法一:先满足条件<f,找到一组最可能满足条件的牛,然后把这些牛按成绩分为两组。成绩较低的一组,用要求aid最大优先队列维护,成绩高的一组用成绩最低优先队列维护,第二组的TOP元素即为中位数。然后遍历剩下的c-n头牛,用分数大于中位数,要求aid加入后(第一组的队首或者第二组的队首中较大者出队后)sum又小于f,将第二组队首出队,push进第一组,把该头牛push进第二组;然后把第一组的队首pop
    解法二:将牛按成绩降序排列,判断中位数为哪个时,符合calf[i].aid+calf[i].left+calf[i].right<f故要求出第i头牛,左边选出half头牛,花费最少的钱,和右边选出half头牛花费最少的钱。用默认优先队列(降序)来维护aid,让aid最大的出列(当新进入的牛的aid小于队首元素)左右都一样,最后让中位数遍历。

AC代码:
解法一:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <functional>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. //解法一:先满足条件<f,找到一组最可能满足条件的牛,然后把这些牛按成绩分为两组
  8. //成绩较低的一组,用要求aid最大优先队列维护,成绩高的一组用成绩最低优先队列维护,第二组的TOP元素即为中位数。
  9. //然后遍历剩下的c-n头牛,用分数大于中位数,要求aid加入后(第一组的队首或者第二组的队首中较大者出队后)sum又小于f
  10. //将第二组队首出队,push进第一组,把该头牛push进第二组;然后把第一组的队首pop
  11. #define ll long long
  12. #define pq priority_queue
  13. using namespace std;
  14. const ll maxn = 1e5+5;
  15. typedef struct moo{
  16. int score,aid;
  17. }model;
  18. model calf[maxn];
  19. struct cmp1{
  20. bool operator() (model a,model b){
  21. return a.aid < b.aid;
  22. }
  23. };
  24. struct cmp2{
  25. bool operator() (model a,model b){
  26. if(a.score == b.score) return a.aid < b.aid;
  27. else return a.score > b.score;
  28. }
  29. };
  30. bool cmp3(model a,model b){
  31. if(a.aid == b.aid) return a.score > b.score;
  32. else return a.aid < b.aid;
  33. }
  34. bool cmp4(model a,model b){
  35. return a.score < b.score;
  36. }
  37. int main(){
  38. //freopen("in.txt","r",stdin);
  39. ll n,c,f;
  40. ll i;
  41. ll half,ans,sum;
  42. model t1,t2,temp;
  43. priority_queue<model,vector<model>,cmp1> maxp;
  44. priority_queue<model,vector<model>,cmp2> minp;
  45. scanf("%lld%lld%lld",&n,&c,&f);
  46. for(i = 0;i < c;i++){
  47. scanf("%lld%lld",&calf[i].score,&calf[i].aid);
  48. }
  49. sort(calf,calf+c,cmp3);
  50. sort(calf,calf+n,cmp4);
  51. half = n/2;
  52. sum = 0;
  53. for(i = 0;i < half;i++){
  54. maxp.push(calf[i]);
  55. sum += calf[i].aid;
  56. }
  57. for(;i < n;i++){
  58. minp.push(calf[i]);
  59. sum += calf[i].aid;
  60. }
  61. temp = minp.top();
  62. ans = temp.score;
  63. if(sum <= f){
  64. for(; i < c; i++){
  65. if(n > 1){
  66. t1 = maxp.top();
  67. t2 = minp.top();
  68. if(calf[i].score > ans && sum - max(t1.aid,t2.aid) + calf[i].aid <= f){
  69. minp.pop();
  70. minp.push(calf[i]);
  71. maxp.push(t2);
  72. temp = maxp.top();
  73. maxp.pop();
  74. t2 = minp.top();
  75. ans = t2.score;
  76. sum = sum - temp.aid + calf[i].aid;
  77. }
  78. }
  79. else{
  80. if(calf[i].score > ans && calf[i].aid <= f){
  81. ans = calf[i].score;
  82. }
  83. }
  84. }
  85. printf("%lld\n",ans);
  86. }
  87. else printf("-1\n");
  88. return 0;
  89. }

解法二:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <functional>
  5. #include <cstdlib>
  6. #include <algorithm>
  7. //将牛按成绩降序排列,判断中位数为哪个时,符合calf[i].aid+calf[i].left+calf[i].right < f
  8. //故要求出第i头牛,左边选出half头牛,花费最少的钱,和右边选出half头牛花费最少的钱。
  9. //用默认优先队列(降序)来维护aid,让aid最大的出列(当新进入的牛的aid小于队首元素)
  10. //左右都一样,最后让中位数遍历。
  11. #define ll long long
  12. #define pq priority_queue
  13. using namespace std;
  14. const ll maxn = 1e5+5;
  15. typedef struct moo{
  16. int score;
  17. ll aid;
  18. ll left;
  19. ll right;
  20. }model;
  21. model calf[maxn];
  22. bool cmp(model a,model b){
  23. if(a.score == b.score) return a.aid < b.aid;
  24. else return a.score > b.score;
  25. }
  26. pq<int> q1,q2;
  27. int main(){
  28. //freopen("in.txt","r",stdin);
  29. int n,c;
  30. int half;
  31. ll f;
  32. int i;
  33. ll sum;
  34. scanf("%d%d%lld",&n,&c,&f);
  35. for(i = 0;i < c;i++){
  36. scanf("%d%lld",&calf[i].score,&calf[i].aid);
  37. calf[i].left = 0;
  38. calf[i].right = 0;
  39. }
  40. sort(calf,calf+c,cmp);
  41. half=n/2;
  42. if(n > 1)
  43. {
  44. sum = 0;
  45. for(i = 0; i < half; i++)
  46. {
  47. q1.push(calf[i].aid);
  48. sum += calf[i].aid;
  49. }
  50. calf[half].left = sum;
  51. for(i = half+1; i < c-half; i++)
  52. {
  53. if(q1.top() > calf[i-1].aid)
  54. {
  55. sum = sum-q1.top()+calf[i-1].aid;
  56. q1.pop();
  57. q1.push(calf[i-1].aid);
  58. }
  59. calf[i].left = sum;
  60. }
  61. sum = 0;
  62. for(i = c-1; i > c-half-1; i--)
  63. {
  64. q2.push(calf[i].aid);
  65. sum += calf[i].aid;
  66. }
  67. calf[c-half-1].right = sum;
  68. for(i = c-half-2; i >= half; i--)
  69. {
  70. if(q2.top() > calf[i+1].aid)
  71. {
  72. sum = sum-q2.top()+calf[i+1].aid;
  73. q2.pop();
  74. q2.push(calf[i+1].aid);
  75. }
  76. calf[i].right = sum;
  77. }
  78. }
  79. for(i = half;i <= c-half-1;i++){
  80. if(calf[i].aid+calf[i].left+calf[i].right <= f){
  81. printf("%d\n",calf[i].score);
  82. break;
  83. }
  84. }
  85. if(i > c-half-1) printf("-1\n");
  86. return 0;
  87. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注