[关闭]
@lawk97 2017-04-19T16:24:02.000000Z 字数 4688 阅读 1028

寒假专题训练--花式STL

VJ地址

STL


A - Moo University - Financial Aid

POJ - 2010
- 题意
奶牛大学招生啦。有C只奶牛申请,会录取N只(N为奇数)。每只奶牛上学需要不同数额的赞助,而学校可以用于赞助奶牛学生的总经费为F。在学校经费的限制下,要使录取的N只奶牛TA们的成绩中位数尽可能高,求出这中位数的可能最大值。
- 思路
首先将奶牛按成绩高低排序。
因为要录取N只奶牛,所以成绩是中位数的奶牛在所有奶牛中的次序必然在[N/2+1,C-N/2]之间取值。在TA前面的奶牛和在TA后面的奶牛,各录取需赞助少的N/2只。如果TA所需的赞助加上其他奶牛需要的赞助之和,小于等于总经费F,则说明这只奶牛的成绩可以作为中位数。
在可作为“中间奶牛”的奶牛中,取成绩的最高的那个。
使用优先队列,便于找到当前奶牛前面和后面的,需赞助少的N/2只。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cmath>
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <string>
  7. #include <queue>
  8. using namespace std;
  9. int n,c,f;
  10. int ans=-1;
  11. int lef[100005],rig[100005];
  12. struct student
  13. {
  14. int score,cost;
  15. }cow[100005];
  16. priority_queue<int>q1,q2;
  17. int cmp(student a,student b)
  18. {
  19. return a.score<b.score;
  20. }
  21. int main()
  22. {
  23. scanf("%d%d%d",&n,&c,&f);
  24. for(int i=0;i<c;i++)
  25. scanf("%d%d",&cow[i].score,&cow[i].cost);
  26. sort(cow, cow+c, cmp);
  27. int l=n/2,r=c-n/2-1;
  28. int sum1=0,sum2=0;
  29. for(int i=0;i<l;i++)
  30. {
  31. sum1+=cow[i].cost;
  32. q1.push(cow[i].cost);
  33. }
  34. for(int i=l;i<=r;i++)
  35. {
  36. lef[i]=sum1;
  37. q1.push(cow[i].cost);
  38. int top=q1.top();
  39. sum1+=cow[i].cost-top;
  40. q1.pop();
  41. }
  42. for(int i=c-1;i>r;i--)
  43. {
  44. sum2+=cow[i].cost;
  45. q2.push(cow[i].cost);
  46. }
  47. for(int i=r;i>=l;i--)
  48. {
  49. rig[i]=sum2;
  50. q2.push(cow[i].cost);
  51. int top=q2.top();
  52. sum2+=cow[i].cost-top;
  53. q2.pop();
  54. }
  55. for(int i=r;i>=l;i--)
  56. {
  57. if(cow[i].cost+lef[i]+rig[i]<=f)
  58. {
  59. ans=cow[i].score;
  60. break;
  61. }
  62. }
  63. printf("%d\n",ans);
  64. return 0;
  65. }

B - Sockets

CodeForces - 732E
- 题意
有n台电脑,m个插座,若电脑与插座电压相同,则可以将其连接并正常使用该电脑。也可将插座与适配器相连,转化为一个电压为原值一半(向上取整)的新插座。已知适配器数量充足。
求最多有多少台电脑可用,若有多种方案,以适配器使用量最少的一种为优。
- 思路
电源的电压只能降低,不能升高。
若一个电源的电压,既可以适配一个需电压大的电脑,又可以适配一个需电压小的电脑,那么使他适配需电压大的电脑,既可以保证尽可能多的电脑被供能(贪心),又可以减少适配器的使用。
所需电压比各种电源的供电压最大值还大的电脑,一定不能使用。
所供电压比各种电脑的需电压最大值还大的电源,如果不用适配器,肯定不可以接任何电脑。
因此,可将电源和电脑分别按电压从大到小排序,进行比对。因为电源电压可以变化,且我们需要尽可能控制适配器的使用,所以使用优先队列来放置电源。放置电源的优先队列中,电压高的优先,电压相等的电源所用适配器少的优先。
具体思路如下程序。
- 代码

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <map>
  7. #include <stack>
  8. #include <queue>
  9. using namespace std;
  10. int n,m,use=0,sum=0;
  11. struct sw{
  12. int id,vol,num;
  13. friend bool operator <(sw a ,sw b){//优先队列默认队头元素最大
  14. if(a.vol!=b.vol)
  15. return a.vol<b.vol;
  16. return a.num>b.num;
  17. }
  18. }s[200005];
  19. struct cu{
  20. int id,vol,ans;
  21. }c[200005];
  22. priority_queue<sw> pq;
  23. int cmp_id(cu a,cu b){
  24. return a.id<b.id;
  25. }
  26. int cmp_v(cu a ,cu b){
  27. return a.vol>b.vol;
  28. }
  29. int main(){
  30. scanf("%d%d",&n,&m);
  31. for(int i=0;i<n;i++){
  32. scanf("%d",&c[i].vol);
  33. c[i].id=i+1;
  34. c[i].ans=0;
  35. }
  36. for(int i=0;i<m;i++){
  37. sw si;
  38. scanf("%d",&s[i].vol);
  39. s[i].id=i+1;
  40. s[i].num=0;
  41. pq.push(s[i]);
  42. }
  43. sort(c,c+n,cmp_v);
  44. for(int i=0;i<n;i++){
  45. if (pq.empty())
  46. {
  47. break;
  48. }
  49. sw f=pq.top();
  50. if(f.vol==c[i].vol){
  51. pq.pop();
  52. c[i].ans=f.id;
  53. s[f.id-1]=f;
  54. sum+=f.num;
  55. use++;
  56. }else if(f.vol>c[i].vol){
  57. pq.pop();
  58. f.num++;
  59. f.vol=ceil(1.0*f.vol/2);
  60. pq.push(f);
  61. i--;
  62. }
  63. }
  64. sort(c,c+n,cmp_id);
  65. printf("%d %d\n",use,sum );
  66. for(int i=0;i<m;i++){
  67. if (i!=0)
  68. {
  69. printf(" ");
  70. }
  71. printf("%d",s[i].num );
  72. }
  73. printf("\n");
  74. for(int i=0;i<n;i++){
  75. if (i!=0)
  76. {
  77. printf(" ");
  78. }
  79. printf("%d",c[i].ans );
  80. }
  81. printf("\n");
  82. return 0;
  83. }

C - HDU Today

HDU - 2112

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <string>
  7. #include <map>
  8. #include <stack>
  9. #include <queue>
  10. using namespace std;
  11. #define INF 1000005
  12. int n,dir,num,minx,now,ans;
  13. int used[155],sl[155],gra[155][155];
  14. string be,st;
  15. map<string,int> m;
  16. int main(){
  17. while(~scanf("%d",&n)&&n!=-1){
  18. cin>>be>>st;
  19. num=1;
  20. minx=INF;
  21. ans=INF;
  22. m.clear();
  23. memset(sl,0,sizeof(sl));
  24. memset(used,0,sizeof(used));
  25. for (int i = 0; i < 155; ++i)
  26. {
  27. for (int j = 0; j < 155; ++j)
  28. {
  29. gra[i][j]=INF;
  30. if (i==j)
  31. {
  32. gra[i][j]=0;
  33. }
  34. }
  35. }
  36. m[be]=num++;
  37. m[st]=num++;
  38. if (be==st)
  39. {
  40. ans=0;
  41. /*
  42. must do it to stop the program,
  43. because there are a wrong m[be]=2
  44. */
  45. }
  46. for(int i=0;i<n;i++){
  47. cin>>be>>st;
  48. scanf("%d",&dir);//opertion 'cin' spend too much time
  49. if(m[be]==0){
  50. m[be]=num++;
  51. }
  52. if(m[st]==0){
  53. m[st]=num++;
  54. }
  55. gra[m[be]][m[st]]=dir;
  56. gra[m[st]][m[be]]=dir;//no direction
  57. }
  58. if (ans==0)
  59. {
  60. printf("%d\n",ans );
  61. continue;
  62. }
  63. for(int i=1;i<num;i++){
  64. sl[i]=gra[1][i];
  65. }
  66. used[1]=1;
  67. now=1;
  68. //now must have initial value,if the begin point can't connect to others,
  69. for (int i = 2; i < num; ++i)
  70. {
  71. minx=INF;
  72. for(int j=1;j<num;j++){
  73. if (!used[j]&&sl[j]<minx)
  74. {
  75. now=j;
  76. minx=sl[j];
  77. }
  78. }
  79. used[now]=1;
  80. for (int j = 1; j < num; ++j)
  81. {
  82. if (!used[j]&&sl[now]+gra[now][j]<sl[j])
  83. {
  84. sl[j]=sl[now]+gra[now][j];
  85. }
  86. }
  87. }
  88. if (sl[2]<INF)
  89. {
  90. printf("%d\n",sl[2] );
  91. }else{
  92. printf("-1\n");
  93. }
  94. }
  95. return 0;
  96. }

F - Pearls in a Row

CodeForces - 620C

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <cstring>
  6. #include <map>
  7. using namespace std;
  8. int n,l,r,num,flag;
  9. int anl[300005],anr[300005];
  10. map<int,int> p;
  11. int main(){
  12. scanf("%d",&n);
  13. l=1;
  14. r=2;
  15. num=0;
  16. flag=0;
  17. for(int i=1;i<=n;i++){
  18. int now;
  19. scanf("%d",&now);
  20. if (!flag&&p[now]>0) {
  21. r=i;
  22. flag=1;
  23. }
  24. if(flag&&p[now]>r){
  25. anl[num]=l;
  26. anr[num]=r;
  27. num++;
  28. l=r+1;
  29. r=i;
  30. }
  31. if (i==n) {
  32. anl[num]=l;
  33. anr[num]=n;
  34. num++;
  35. }
  36. p[now]=i;
  37. }
  38. if (flag) {
  39. printf("%d\n",num);
  40. for (int i=0; i<num; i++) {
  41. printf("%d %d\n",anl[i],anr[i]);
  42. }
  43. }else{
  44. printf("-1\n");
  45. }
  46. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注