题目分类:优先队列+STL
作者:ACShiryu
做题时间:2011-7-18
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 217 Accepted Submission(s): 107
题目大意是路上有很多石头,当你遇到奇数序列的石头就把他向前仍,偶数的不动他,如果两个石头一起,先考虑可以仍的比较近的石头仍也就是比较大的石头,这样一直下去,直到前面所有的石头都不可以仍了为止,求最远的石头距离起点多少题目这题用优先队列非常方便.
分析;可以定义一个结构体,分别存储石头现在的位置和能能出去的距离到优先队列中,然后每次取“最小的”,如果取得是偶数个就不动,取得是奇数个就要更新该石头的位置并重新存到优先队列中,直到队列空,输出最后一个石头的位置
数据分析:程序的时间复杂度是O(nlogn),数据量最大为100,000,不会超时。要特别注意多个石头的x一样的情况,要优先考虑y值最小的那块石头
参考代码:
1 #include<iostream>
2 #include<cstdlib>
3 #include<cstdio>
4 #include<cstring>
5 #include<algorithm>
6 #include<cmath>
7 #include<queue>
8 using namespace std;
9 struct Stone{
10 int x; //石头的初始地
11 int y; //石头能扔的最远距离
12 };
13 bool operator<( Stone a, Stone b )
14 { //重载小于,按照结构体中x小的在队顶,如果x一样,则按照y的最小的在//队顶
15 if( a.x== b.x ) return a.y > b.y;
16 return a.x > b.x;
17 }
18 int main()
19 {
20 int t;
21 scanf("%d",&t);//测试数据个数
22 while(t--)
23 {
24 int n;
25 int i ;
26 priority_queue<Stone>que; //定义一个Stone成员的优先//队列
27 scanf("%d",&n);
28 Stone tmp;
29 for(i =0;i< n ; i++ )
30 {
31 scanf("%d%d",&tmp.x,&tmp.y);
32 que.push(tmp);//入队
33 }
34 int sum =1;//判断碰到的是第几个石头的标记
35 while(!que.empty())//当队列为空就跳出循环,也就是说再//向前就没有石头可以遇到
36 {
37 tmp = que.top();//去队顶元素,也就是在后面的所有//石头中第一个碰到的石头
38 que.pop();//出对
39 if(sum%2)
40 {//如果是奇数号石头,则处理,否则不做处理
41 tmp . x+=tmp.y;//则向前扔y单位长度
42 que.push(tmp);//扔出去的石头入队
43 }
44 sum++;//石头计数+1
45 }
46 printf("%d\n",tmp.x);//打印最后一块石头的坐标就是所求//的最远距离
47 }
48 return 0;
49 }