[关闭]
@morehigh 2017-02-25T03:13:29.000000Z 字数 3135 阅读 992

CQUPT 集训队专题训练(花式STL)

STL

b

A - Moo University - Financial Aid
题意:

  1. C(N <= C <= 100,000)头奶牛,现要招收N(1 <= N <= 19999)头奶牛上大学,给定每头奶牛的智商和所需补助,并给定最大可提供补助和F,0 <= F <= 2000000000,求补助奶牛的智商最大中位数

解题思路:

  1. 将奶牛按智商从小到大排序,然后枚举中位数,那么问题就是如何确定中位数左右分别选取n/2头奶牛的最小费用,这个可以通过堆预处理得出,(堆的维护要用到优先队列),正向扫描一遍每次看当前奶牛所需费用是否小于堆顶元素费用,若小于队顶出堆,当前奶牛费用入堆.反向同理,然后枚举一下中位数即可

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. const int inf=10*0x7ffffff;
  7. using namespace std;
  8. long long s1[100050],s2[100050];
  9. struct Node
  10. {
  11. int fir,sec;
  12. bool operator< (const Node &a) const
  13. {
  14. return sec<a.sec;
  15. }
  16. }cow[100050];
  17. bool cmp(Node x,Node y)
  18. {
  19. return x.fir<y.fir;
  20. }
  21. int main()
  22. {
  23. int n,c,f;
  24. // cout<<inf<<" "<<10*0x7ffffff<<endl;
  25. while(~scanf("%d%d%d",&n,&c,&f))
  26. {
  27. for(int i=0;i<c;i++)
  28. scanf("%d%d",&cow[i].fir,&cow[i].sec);
  29. sort(cow,cow+c,cmp);
  30. priority_queue<Node> pq;
  31. int sum=0;
  32. for(int i=0;i<c;i++)
  33. {
  34. s1[i]=inf;
  35. if(i<n/2)
  36. {
  37. pq.push(cow[i]);
  38. sum+=cow[i].sec;
  39. continue;
  40. }
  41. s1[i]=sum;
  42. if(cow[i].sec>=pq.top().sec)continue;
  43. sum-=pq.top().sec;
  44. pq.pop();
  45. sum+=cow[i].sec;
  46. pq.push(cow[i]);
  47. }
  48. sum=0;
  49. while(!pq.empty())pq.pop();
  50. for(int i=c-1;i>=0;i--)
  51. {
  52. s2[i]=inf;
  53. if(i>c-1-n/2)
  54. {
  55. pq.push(cow[i]);
  56. sum+=cow[i].sec;
  57. continue;
  58. }
  59. s2[i]=sum;
  60. if(cow[i].sec>=pq.top().sec)continue;
  61. sum-=pq.top().sec;
  62. pq.pop();
  63. sum+=cow[i].sec;
  64. pq.push(cow[i]);
  65. }
  66. int ans=-1;
  67. for(int i=c-1-n/2;i>=n/2;i--)
  68. {
  69. // cout<<s1[i]<<s2[i]<<" "<<cow[i].sec<<endl;
  70. if(s1[i]+s2[i]+cow[i].sec<=f)
  71. {
  72. ans=cow[i].fir;
  73. break;
  74. }
  75. }
  76. printf("%d\n",ans);
  77. }
  78. return 0;
  79. }

C - HDU Today
题意:

  1. N(0<=N<=10000)是公交车总数,从起始点start到终点end,有n行每一行有一个s,e分别代表车站的站名,和时间t.求坐公交车的最短时间,

解题思路:

  1. 首先考虑到要用 dijkstra算法求最短时间,不过每一站的站名是字符串,需要用map将字符串映射为数字,便于处理

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <map>
  6. #include <string>
  7. #include <cmath>
  8. #define inf 0x3f3f3f3f
  9. using namespace std;
  10. char start[100],endd[100],s[100],e[100];
  11. int t,ma[200][200],dis[200],vis[200];
  12. void dijkstra()
  13. {
  14. memset(vis,0,sizeof(vis));
  15. for(int i=1;i<=t;i++)
  16. dis[i]=ma[1][i];
  17. dis[1]=0;
  18. vis[1]=1;
  19. for(int i=1;i<=t;i++)
  20. {
  21. int mm=inf,mk=-1;
  22. for(int j=1;j<=t;j++)
  23. {
  24. if(mm>dis[j]&&!vis[j])
  25. {
  26. mm=dis[j];
  27. mk=j;
  28. }
  29. }
  30. if(mk==-1)
  31. break;
  32. vis[mk]=1;
  33. for(int j=1;j<=t;j++)
  34. {
  35. if(dis[j]>dis[mk]+ma[mk][j]&&!vis[j])
  36. dis[j]=dis[mk]+ma[mk][j];
  37. }
  38. }
  39. }
  40. int main()
  41. {
  42. int n,w;
  43. map<string,int> q;
  44. while(scanf("%d",&n),n!=-1)
  45. {
  46. memset(ma,inf,sizeof(ma));
  47. scanf("%s%s",start,endd);
  48. q.clear();
  49. q[start]=1;
  50. q[endd]=2;
  51. t=3;
  52. for(int i=0;i<n;i++)
  53. {
  54. scanf("%s%s%d",s,e,&w);
  55. if(!q[s])
  56. q[s]=t++;
  57. if(!q[e])
  58. q[e]=t++;
  59. if(ma[q[s]][q[e]]>w)
  60. ma[q[e]][q[s]]=ma[q[s]][q[e]]=w;
  61. }
  62. if(strcmp(start,endd)==0)
  63. {
  64. printf("0\n");
  65. continue;
  66. }
  67. dijkstra();
  68. if(dis[2]==inf)
  69. printf("-1\n");
  70. else
  71. printf("%d\n",dis[2]);
  72. }
  73. return 0;
  74. }

F - Pearls in a Row
题意:

  1. 一个长度为n (1 ≤ n ≤ 3·105)的字符串,从中截取一段,如果这一段中有两个相同的数字,则为一个好串,求出有多少个这样的子串和这个子串的左右端点

解题思路:

  1. 直接将序列中出现的点标记为1,然后如果下一次出现的话,就记录一下左右端点,并将子串数目加1,加标记的1取消,继续遍历此序列

代码:

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