【2018.08.01】(表/栈/队列/大小顶堆)学习Stark和Queue算法小记

Train Problem I

As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Station is the fastest all over the world ^v^). But here comes a problem, there is only one railway where all the trains stop. So all the trains come in from one side and get out from the other side. For this problem, if train A gets into the railway first, and then train B gets into the railway before train A leaves, train A can't leave until train B leaves. The pictures below figure out the problem. Now the problem for you is, there are at most 9 trains in the station, all the trains has an ID(numbered from 1 to n), the trains get into the railway in an order O1, your task is to determine whether the trains can get out in an order O2. 
  

InputThe input contains several test cases. Each test case consists of an integer, the number of trains, and two strings, the order of the trains come in:O1, and the order of the trains leave:O2. The input is terminated by the end of file. More details in the Sample Input. 
OutputThe output contains a string "No." if you can't exchange O2 to O1, or you should output a line contains "Yes.", and then output your way in exchanging the order(you should output "in" for a train getting into the railway, and "out" for a train getting out of the railway). Print a line contains "FINISH" after each test case. More details in the Sample Output. 
Sample Input

3 123 321
3 123 312

Sample Output

Yes.
in
in
in
out
out
out
FINISH
No.
FINISH


        
 
For the first Sample Input, we let train 1 get in, then train 2 and train 3.
So now train 3 is at the top of the railway, so train 3 can leave first, then train 2 and train 1.
In the second Sample input, we should let train 3 leave first, so we have to let train 1 get in, then train 2 and train 3.
Now we can let train 3 leave.
But after that we can't let train 1 leave before train 2, because train 2 is at the top of the railway at the moment.
So we output "No.".
上面是我的代码,但是超时了,下面是其他人的代码,我去研究研究他的算法吧
他的算法很酷,他想到了一些我没想到的地方,比如说第一步一定是进第一个,我的算法偏慢,先处理数组,再处理堆栈,他是直接对堆栈和数组同时一起处理,能从堆栈里面拉出来的立马拉出来
#include<iostream>
#include<stack>
#define max 100
using namespace std;
/*int n;
bool step[21];
int main(void)
{
    stack<char> Q;
    int O1sign, O2sign, stepsign;
    char a[10], b[10];
    while ( scanf("%d", &n), n )
    {
        getchar();//防止第一个字符 
        memset( step, false , sizeof(step) ); 
        while ( !Q.empty() ) Q.pop();
        //把堆栈里面清理干净,每一步的step也都清零 
        O1sign=1;    O2sign=1;    stepsign=1;
        //初始化所有数据 
        scanf("%s%s", a+1, b+1);
        while ( 1 )
        {
            if ( a[O1sign]!=b[O2sign] )//如果这两者不相等 
            {
                step[stepsign++]=true;
                Q.push(a[O1sign]); 
                //那么先把O1上的这个字母塞入堆栈
            }
            else//这两个字母相等呢?
            {
                step[stepsign++]=true;
                step[stepsign++]=false;
                O2sign++; 
                //进去了马上就出来了
            }
            if ( O1sign == n ) break;
            //此时已经完成了整个O1的判断,跳出循环 
            O1sign++;
            //不论结果怎样,O1sign都要往后推一格 
        }
        while ( !Q.empty() )
        {
            if ( Q.top() == b[O2sign] )
            {
                Q.pop();
                O2sign++;
                step[stepsign++]=false;
            }
            else break;
        }
        if ( stepsign == 2*n+1 )
        {
            printf("Yes.
");
            for (int i=1 ; i<=2*n ; i++ )
            {
                if ( step[i] == true ) printf("in
");
                if ( step[i] == false ) printf("out
");
            }
            printf("FINISH
");
        }
        else
        {
            printf("No.
FINISH
");    
        }
    }
    return 0;
}*/
int main()
{
    stack<char>s;
    int n,i,j,k,result[max];//n为列车个数, result数组用来表示结果,1表示进栈。0表示出
    char str1[max],str2[max];//序列1和序列2
    while(cin>>n>>str1>>str2)
    {
        j=0,i=0,k=1;
        s.push(str1[0]);//为防止栈空,压一个进去
        result[0]=1;//记录进来了一个。
        while(i<n&&j<n)
        {
            if(s.size()&&s.top()==str2[j])
            {//如果栈顶元素与序列2当前的元素相等,则弹栈,序列2集团向后移一位。
                j++;
                s.pop();
                result[k++]=0;
            }
            else
            {//否则从序列1中取当前元素压入栈中。
                if(i==n)break;
                s.push(str1[++i]);
                result[k++]=1;
            }
        }
        if(i==n)//如果I==N表示栈顶元素不等于序列2当前元素,且序列1中元素都已经入过栈,判断不能得到序列2一样的答案。
            cout<<"No."<<endl;
        else
        {//输出进出栈方式
            cout<<"Yes."<<endl;
            for(i=0; i<k; i++)
                if(result[i])
                    cout<<"in"<<endl;
                else
                    cout<<"out"<<endl;
        }
        cout<<"FINISH"<<endl;
    }
    return 0;
}

Replace To Make Regular Bracket Sequence

 

You are given string s consists of opening and closing brackets of four kinds <>, {}, [], (). There are two types of brackets: opening and closing. You can replace any bracket by another of the same type. For example, you can replace < by the bracket {, but you can't replace it by ) or >.

The following definition of a regular bracket sequence is well-known, so you can be familiar with it.

Let's define a regular bracket sequence (RBS). Empty string is RBS. Let s1 and s2 be a RBS then the strings <s1>s2{s1}s2[s1]s2(s1)s2are also RBS.

For example the string "[[(){}]<>]" is RBS, but the strings "[)()" and "][()()" are not.

Determine the least number of replaces to make the string s RBS.

Input

The only line contains a non empty string s, consisting of only opening and closing brackets of four kinds. The length of s does not exceed 106.

Output

If it's impossible to get RBS from s print Impossible.

Otherwise print the least number of replaces needed to get RBS from s.

Examples
Input
[<}){}
Output
2
Input
{()}[]
Output
0
Input
]]
Output
Impossible
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue> 
using namespace std;
#define MAXN 1000050 
/*拿到这道题目,题意还算好理解,但我对堆栈还不是很理解,所以去看看别人的代码吧*/
/*想法是将左括号压入堆栈中*/ 

char a[MAXN];

bool judge( char a, char b )
{
    if ( a=='(' && b==')' ) return false;
    if ( a=='<' && b=='>' ) return false;
    if ( a=='{' && b=='}' ) return false;
    if ( a=='[' && b==']' ) return false;
    return true;
} 

int main(void)
{
    int len, i, sum=0;
    stack<char> Q;
    scanf("%s", a);
    len=strlen(a);
    for ( i=0 ; i<len ; i++ )
    {
        if ( a[i]=='(' || a[i]=='{' || a[i]=='<' || a[i]=='[')
        {
            Q.push(a[i]);//将这个左括号放进堆栈中哦 
        }
        else
        {
            if ( Q.empty() )//如果没有左括号来匹配的话 
            {
                cout<<"Impossible"<<endl;
                return 0;//告辞 
            }
            if ( judge( Q.top() , a[i]) )
            {
                sum++;
            }
            Q.pop();//要记得丢掉哦 
        }
    }
    if ( Q.empty() ) cout<<sum<<endl;
        else cout<<"Impossible"<<endl;
    return 0;
}

Rails

There is a famous railway station in PopPush City. Country there is incredibly hilly. The station was built in last century. Unfortunately, funds were extremely limited that time. It was possible to establish only a surface track. Moreover, it turned out that the station could be only a dead-end one (see picture) and due to lack of available space it could have only one track. 

The local tradition is that every train arriving from the direction A continues in the direction B with coaches reorganized in some way. Assume that the train arriving from the direction A has N <= 1000 coaches numbered in increasing order 1, 2, ..., N. The chief for train reorganizations must know whether it is possible to marshal coaches continuing in the direction B so that their order will be a1, a2, ..., aN. Help him and write a program that decides whether it is possible to get the required order of coaches. You can assume that single coaches can be disconnected from the train before they enter the station and that they can move themselves until they are on the track in the direction B. You can also suppose that at any time there can be located as many coaches as necessary in the station. But once a coach has entered the station it cannot return to the track in the direction A and also once it has left the station in the direction B it cannot return back to the station. 

Input

The input consists of blocks of lines. Each block except the last describes one train and possibly more requirements for its reorganization. In the first line of the block there is the integer N described above. In each of the next lines of the block there is a permutation of 1, 2, ..., N. The last line of the block contains just 0. 

The last block consists of just one line containing 0.

Output

The output contains the lines corresponding to the lines with permutations in the input. A line of the output contains Yes if it is possible to marshal the coaches in the order required on the corresponding line of the input. Otherwise it contains No. In addition, there is one empty line after the lines corresponding to one block of the input. There is no line in the output corresponding to the last ``null'' block of the input.

Sample Input

5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0

Sample Output

Yes
No

Yes
/*以下是我的代码,但是一直频繁出现错误,结果越修改越像其他人的代码了*/
#include <iostream>
#include <cstdio>
#include <stack>
#define MAXN 1010
using namespace std;
/*检查了好久,因为一直出现Output limit,所以一直在printf处修改,想不到居然会是输
入的时候出现的错误*/ 
int n, b[MAXN], i, k, a;
bool sign;

int main(void)
{
    while ( scanf("%d", &n) , n )//就是这里出现的错误 
    {
        while ( scanf("%d", &b[1]) , b[1] )
        {
            for ( i=2 ; i<=n ; i++ )
            {
                scanf("%d", &b[i] );
            }//输入 
            stack<int> Q;
            sign=true;
            a=1;//a代表着从1~n的数组;
            k=1; 
            while( k<=n )//这边是条件是k<=n 
            {
                if ( a == b[k] )
                {
                    a++;
                    k++;
                }
                else if ( !Q.empty() && Q.top() == b[k] )
                {
                    k++;
                    Q.pop();
                }
                else if ( a<=n )//应该是不满足上述条件后,都要把下一个点放入
                {//并且这个数组还是顺序递增的 
                    Q.push( a++ );
                }
                else
                {//一般都不会进行到最后一步,进行到这里说明也就凉了呀 
                    sign=false;
                    break;
                }
            }
            printf("%s
", sign?"Yes":"No");
        }
    }
    return 0;
}
/*以下是参考代码*/
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
const int maxn = 1010;
int n,t[maxn]; 
int main(int argc, char** argv) 
{
    while(scanf("%d",&n)!=-1&&n)
    {
        while( scanf("%d",&t[1]) , t[1])
        {
            for(int i=2 ; i<=n ; i++ )    scanf("%d",&t[i]);
            bool flag=true;
            int a=1,b=1;
            stack<int> s;
            while(b<=n)
            {
                if(a==t[b])
                {
                    a++;b++;
                }
                else if(!s.empty()&&s.top()==t[b])
                {
                    s.pop();b++;
                }
                else if(a<=n)
                {
                    s.push(a++);
                }
                else
                {
                    flag=false;break;
                }
            }
            printf("%s
",flag?"Yes":"No");
        }
        cout<<endl;
        
    }
    return 0;
}

看病要排队

看病要排队这个是地球人都知道的常识。 
不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻重,所以不能根据简单的先来先服务的原则。所以医院对每种病情规定了10种不同的优先级。级别为10的优先权最高,级别为1的优先权最低。医生在看病时,则会在他的队伍里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。 

现在就请你帮助医院模拟这个看病过程。

Input输入数据包含多组测试,请处理到文件结束。 
每组数据第一行有一个正整数N(0<N<2000)表示发生事件的数目。 
接下来有N行分别表示发生的事件。 
一共有两种事件: 
1:"IN A B",表示有一个拥有优先级B的病人要求医生A诊治。(0<A<=3,0<B<=10)
2:"OUT A",表示医生A进行了一次诊治,诊治完毕后,病人出院。(0<A<=3)Output对于每个"OUT A"事件,请在一行里面输出被诊治人的编号ID。如果该事件时无病人需要诊治,则输出"EMPTY"。 
诊治人的编号ID的定义为:在一组测试中,"IN A B"事件发生第K次时,进来的病人ID即为K。从1开始编号。 
Sample Input

7
IN 1 1
IN 1 2
OUT 1
OUT 2
IN 2 1
OUT 2
OUT 1
2
IN 1 1
OUT 1

Sample Output

2
EMPTY
3
1
1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue> 
using namespace std;
/*这道题我看了一下,貌似用不到队列和堆栈,因为病人也有轻重等级,而堆栈和队列只有
先进后出和先进先出的区别,无法判断病况深不深,我觉得结构体就可以解决,建立三个结
构体代表三名医生,里面一个bool代表出没出院,两个int代表ID和病况,每次要OUT一个从
里面检索挑出病况最重的且未出院的(但是这样觉得好费时= =)*/
/*网上提到的是大顶堆的知识,又学到了新知识了~自己先尝试模拟一下吧*/
/*找了老半天的BUG,原来是错在运算符重载里面了,那个地方我做个标记*/
class patient//每一个医生都是一个大顶堆,里面都是病人 
{
    public:
        int id, level;
        friend bool operator < ( patient a, patient b)
        {
            if ( a.level != b.level ) return a.level < b.level;
                else return a.id < b.id;/*就是这个地方了= =找了好久好久*/
                /*我大概理解了,这一步就是为了比较先后来的顺序,
                id比较小的话才先操作*/
        }
};
int main(void)
{
    int n, doctor, level, i, Count;
    char s[5];
    patient temp;
    priority_queue< patient , vector<patient> , less<patient> > doctors[4];
    while ( scanf("%d", &n) != EOF )
    {
        getchar();
        for ( i=1 ; i<=3 ; i++ )
        {
            while ( !doctors[i].empty() ) doctors[i].pop(); 
        }//清空医生的队列 
        Count=1;//用来记录病人的ID 
        for ( i=1 ; i<=n ; i++ )
        {
            scanf("%s", s);
            if ( s[0]=='I' )
            {
                //cout<<'i'<<endl;
                scanf("%d%d", &doctor, &level);
                temp.id = Count++;
                temp.level = level;
                doctors[doctor].push(temp); 
            }
            else
            {
                //cout<<'o'<<endl;
                scanf("%d", &doctor );
                if ( doctors[doctor].empty() )
                {
                    printf("EMPTY
");
                }
                else
                {
                    printf("%d
", doctors[doctor].top().id );
                    doctors[doctor].pop();
                }
            }
        }
    } 
    return 0;
}

Windows Message Queue

Message queue is the basic fundamental of windows system. For each process, the system maintains a message queue. If something happens to this process, such as mouse click, text change, the system will add a message to the queue. Meanwhile, the process will do a loop for getting message from the queue according to the priority value if it is not empty. Note that the less priority value means the higher priority. In this problem, you are asked to simulate the message queue for putting messages to and getting message from the message queue.

InputThere's only one test case in the input. Each line is a command, "GET" or "PUT", which means getting message or putting message. If the command is "PUT", there're one string means the message name and two integer means the parameter and priority followed by. There will be at most 60000 command. Note that one message can appear twice or more and if two messages have the same priority, the one comes first will be processed first.(i.e., FIFO for the same priority.) Process to the end-of-file.OutputFor each "GET" command, output the command getting from the message queue with the name and parameter in one line. If there's no message in the queue, output "EMPTY QUEUE!". There's no output for "PUT" command.Sample Input

GET
PUT msg1 10 5
PUT msg2 10 4
GET
GET
GET

Sample Output

EMPTY QUEUE!
msg2 10
msg1 10
EMPTY QUEUE!
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue> 
using namespace std;
/*这道题不难,但每次都会出错或者超时,最后才发现是一开始的scanf没有加入EOF*/
struct node
{
    public:
        char name[400];
        int level, num, id;
        friend bool operator < ( node a , node b )
        {
            if ( a.level != b.level ) return a.level > b.level;
                else return a.id > b.id;
        }
}temp; 

int main(void)
{
    priority_queue<node> S;
    char s[4];
    int Count=1;
    while ( scanf("%s",s)!=EOF )
    {
        if ( s[0]=='G' )
        {
            if ( S.empty() )
            {
                printf("EMPTY QUEUE!
");
            }
            else
            {
                temp=S.top();
                printf("%s %d
",temp.name, temp.num);
                S.pop();
            }
        }
        else
        {
            scanf("%s%d%d",temp.name ,&temp.num ,&temp.level);
            //这里有个地方错了就是这个name不用加& 
            temp.id = Count++;
            S.push(temp);
        }
    }
    return 0;
}

The kth great number

Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feeling giddy. Now, try to help Xiao Bao.

InputThere are several test cases. For each test case, the first line of input contains two positive integer n, k. Then n lines follow. If Xiao Ming choose to write down a number, there will be an " I" followed by a number that Xiao Ming will write down. If Xiao Ming choose to ask Xiao Bao, there will be a "Q", then you need to output the kth great number. 
OutputThe output consists of one integer representing the largest number of islands that all lie on one line. 
Sample Input

8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q

Sample Output

1
2
3

Hint

Xiao  Ming  won't  ask  Xiao  Bao  the  kth  great  number  when  the  number  of  the  written number is smaller than k. (1=<k<=n<=1000000).
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue> 
using namespace std;
/*前面学习了大顶堆,但是大顶堆不至于从中间取吧*/
/*这么想的时候,心中突然有了一个想法,用一个大顶堆和一个普通堆栈,用普通堆栈来记
录大顶堆上k-1个元素,取出结果后再还回去(不过这样会不会有点费时呢?),更何况这
次的数量级是10的七次方*/
/*题意:先输入n和k,接下来n个操作,有两种操作,I和Q,I的话输入数,Q的话输出第K个大的数。
思路:用优先队列降序存储输入的数字,一旦队列的元素个数大于K,则将队首元素删除,
这样就能保证队首元素为第K大的数了!
因为如果有新的数插入时应该是第K大的数,则会插入到现在大的第K大的数的后面,删除队
顶元素后,对首就是刚刚插入的数了。如果是较小的数,则会插在队首,删除队首之后,仍
然不会影响第K大的数!*/
/*太机智了,居然用到了小顶堆的办法,将本来在堆栈底的小数放在堆栈顶,求第K个大数
被转化成保留K个大数*/
int main()
{
       int n,k,i,a;
    char s[2]; 
    while( scanf("%d%d",&n,&k)!=EOF )
    {
        priority_queue< int ,vector<int>,greater<int> > q;
        while(n--)
        {
            scanf("%s",s);
            if(s[0]=='I')
            {
                 scanf("%d",&a);
                q.push(a);
                if( q.size() > k ) q.pop();
                //超过大于k个的就删掉    
            } 
            else  printf("%d
",q.top());
        }
    }
    return 0;
}

Black Box

Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are two types of transactions: 

ADD (x): put element x into Black Box; 
GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box. Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non- descending. 

Let us examine a possible sequence of 11 transactions: 

Example 1 

N Transaction i Black Box contents after transaction Answer
(elements are arranged by non-descending)
1 ADD(3) 0 3
2 GET 1 3 3
3 ADD(1) 1 1, 3
4 GET 2 1, 3 3
5 ADD(-4) 2 -4, 1, 3
6 ADD(2) 2 -4, 1, 2, 3
7 ADD(8) 2 -4, 1, 2, 3, 8
8 ADD(-1000) 2 -1000, -4, 1, 2, 3, 8
9 GET 3 -1000, -4, 1, 2, 3, 8 1
10 GET 4 -1000, -4, 1, 2, 3, 8 2
11 ADD(2) 4 -1000, -4, 1, 2, 2, 3, 8

It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type. 


Let us describe the sequence of transactions by two integer arrays: 


1. A(1), A(2), ..., A(M): a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, M <= 30000. For the Example we have A=(3, 1, -4, 2, 8, -1000, 2). 

2. u(1), u(2), ..., u(N): a sequence setting a number of elements which are being included into Black Box at the moment of first, second, ... and N-transaction GET. For the Example we have u=(1, 2, 6, 6). 

The Black Box algorithm supposes that natural number sequence u(1), u(2), ..., u(N) is sorted in non-descending order, N <= M and for each p (1 <= p <= N) an inequality p <= u(p) <= M is valid. It follows from the fact that for the p-element of our u sequence we perform a GET transaction giving p-minimum number from our A(1), A(2), ..., A(u(p)) sequence. 


Input

Input contains (in given order): M, N, A(1), A(2), ..., A(M), u(1), u(2), ..., u(N). All numbers are divided by spaces and (or) carriage return characters.

Output

Write to the output Black Box answers sequence for a given sequence of transactions, one number each line.

Sample Input

7 4
3 1 -4 2 8 -1000 2
1 2 6 6

Sample Output

3
3
1
2
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue>
using namespace std;
/*由于昨天那道题给了我灵感,我想这道题既然是要抽出第几小的数字,那么就应该使用大
顶堆来储存数据,但是有一个难点就是顺序问题*/
/*顺序问题想好了,但是很担心的一点就是2连GET甚至更多,那我原本保留的数字只剩下第
k小的,突然向我索取第k+1小的数字,我在之前已经pop()掉了,没办法给的问题*/
/*网上的思路是使用两个顶堆来解决问题,将大顶堆pop()掉的数字放入小顶堆之中(太机
智了),自己实现试试吧*/
/*感觉我的想法很不好,如果遇到重复get的话就自己在那里循环,还pop掉了,等于说两个
顶堆里都没这个数字了,而我参考的代码里,他的想法就机智多了,他把上面的小顶堆的数
字抠出来放在下面的大顶堆里面再进行下一轮的循环*/
#define MAXN 6000000
int b[MAXN];
__int64 a[MAXN];
priority_queue< __int64 , vector<__int64> , greater<__int64> > small;//小顶堆 
priority_queue< __int64 , vector<__int64> , less<__int64> > big;//大顶堆 
int main(void)
{
    int m ,n, i, j, count;
    while ( scanf("%d%d", &m, &n) != EOF )
    {
        while ( !small.empty() ) small.pop();
        while ( !big.empty() ) big.pop();
        for ( i=1 ; i<=m ; i++ )
        {
            scanf("%I64d", &a[i] );
        }
        for ( i=1 ; i<=n ; i++ )
        {
            scanf("%d", &b[i] );
        }
        sort(b+1,b+n+1);//这句防止B乱序
        count=1;
        for ( i=1 ; i<=m,count<=n ; i++ )//开始遍历数组a 
        {
            big.push(a[i]);//不论怎样先把a数组的数字放入大顶堆 
            if ( big.size() > count-1 )//如果超过大顶堆要保护的数字 
            {
                small.push( ( big.top() ) );//将它塞入小顶堆中 
                big.pop();//删去大顶堆头部 
            }
            if ( i == b[count] ) //如果到了需要输出的时候 
            {
                printf("%I64d
", small.top() );//输出小顶堆最小数字
                while ( b[count+1] == b[count] )
                {
                    small.pop();//如果连续输出的话,把这个输出的数字舍弃
                    printf("%I64d
", small.top() );
                    count++;
                }
                count++; 
            }
            //cout<<small.top()<<' '<<big.top()<<endl;
        }
    }
    return 0;
}

/*#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
#define LL __int64
priority_queue <LL> p1 ;//大顶堆在下 
priority_queue <LL,vector<LL>,greater<LL> > p2 ;//小顶堆在上 
LL a[6000000] ;
int main()
{
    int i , j , n , m , x ;
    while(scanf("%d %d", &n, &m)!=EOF)
    {
        while( !p1.empty() )    p1.pop();
        while( !p2.empty() )    p2.pop() ;
        for(i = 1 ; i <= n ; i++)    scanf("%I64d", &a[i]);
        i = 1 ;
        while( m-- )
        {
            scanf("%d", &x);
            for( ; i<=x ; i++)
            {
                if( p1.empty() || p1.top() < a[i] )
                    p2.push(a[i]);//如果这个a数字比大顶堆来得大,放入小顶堆 
                else
                {
                    p1.push(a[i]);
                    p2.push( ( p1.top() ) );
                    p1.pop();
                }
            }
            printf("%d
", p2.top() );
            p1.push( p2.top() );
            p2.pop();
        }
    }
    return 0;
}
*/

Stones

Because of the wrong status of the bicycle, Sempr begin to walk east to west every morning and walk back every evening. Walking may cause a little tired, so Sempr always play some games this time. 
There are many stones on the road, when he meet a stone, he will throw it ahead as far as possible if it is the odd stone he meet, or leave it where it was if it is the even stone. Now give you some informations about the stones on the road, you are to tell me the distance from the start point to the farthest stone after Sempr walk by. Please pay attention that if two or more stones stay at the same position, you will meet the larger one(the one with the smallest Di, as described in the Input) first. 

InputIn the first line, there is an Integer T(1<=T<=10), which means the test cases in the input file. Then followed by T test cases. 
For each test case, I will give you an Integer N(0<N<=100,000) in the first line, which means the number of stones on the road. Then followed by N lines and there are two integers Pi(0<=Pi<=100,000) and Di(0<=Di<=1,000) in the line, which means the position of the i-th stone and how far Sempr can throw it. 
OutputJust output one line for one test case, as described in the Description. 
Sample Input

2
2
1 5
2 4
2
1 5
6 6

Sample Output

11
12
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
using namespace std;
/*理解了题意后觉得好难= =最后输出的是出发点和最远石头的距离,我觉得这道题应该要
用到struct结构,位置比较靠前(小的)会被先丢出去,所以这道题我觉得应该用小顶堆*/

struct stone
{
    int distance, position;
    friend bool operator > (stone a, stone b)
    {
        if ( a.position != b.position ) return a.position > b.position;
            else return a.distance > b.distance;
    } 
}temp;


int main(void)
{
    int repeat, n, Count;
    priority_queue< stone , vector<stone> , greater<stone> > S;
    scanf("%d", &repeat );
    while ( repeat-- )
    {
        scanf("%d", &n);
        while ( !S.empty() ) S.pop();
        Count=1;
        while ( n-- )
        {
            scanf("%d%d", &temp.position , &temp.distance );
            S.push( temp );
        }
        while ( !S.empty() )
        {
            if ( Count & 1 )//要是得1,说明为奇数 
            {
                temp.position = S.top().distance + S.top().position;
                temp.distance = S.top().distance;
                S.pop();
                S.push( temp );
                Count++;
            }
            else
            {
                if ( S.size() == 1 ) printf("%d
", S.top().position );
                S.pop();
                Count++;
            }
        }
    } 
    return 0;
}
原文地址:https://www.cnblogs.com/mokou/p/9401555.html