Train Problem I
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#include #define max 100 using namespace std; /*int n; bool step[21]; int main(void) { stack 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.\n"); for (int i=1 ; i<=2*n ; i++ ) { if ( step[i] == true ) printf("in\n"); if ( step[i] == false ) printf("out\n"); } printf("FINISH\n"); } else { printf("No.\nFINISH\n"); } } 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(in) { 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 ) 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.
OutputIf it's impossible to get RBS from s print Impossible.
Otherwise print the least number of replaces needed to get RBS from s.
Examples[<}){}
2
{()}[]
0
]]
Impossible
#include#include #include #include #include #include #include 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 ) { 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< endl; else cout<<"Impossible"<<endl; return 0; }
Rails
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 last block consists of just one line containing 0.
Output
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#include #include #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\n", sign?"Yes":"No"); } } return 0; } /*以下是参考代码*/ #include #include #include 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\n",flag?"Yes":"No"); } cout<<endl; } return 0; }
看病要排队
不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻重,所以不能根据简单的先来先服务的原则。所以医院对每种病情规定了10种不同的优先级。级别为10的优先权最高,级别为1的优先权最低。医生在看病时,则会在他的队伍里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。
现在就请你帮助医院模拟这个看病过程。
Input输入数据包含多组测试,请处理到文件结束。
每组数据第一行有一个正整数N(0
一共有两种事件:
1:"IN A B",表示有一个拥有优先级B的病人要求医生A诊治。(02:"OUT A",表示医生A进行了一次诊治,诊治完毕后,病人出院。(0诊治人的编号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#include #include #include #include #include #include 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 , less > 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'< scanf("%d%d", &doctor, &level); temp.id = Count++; temp.level = level; doctors[doctor].push(temp); } else { //cout<<'o'< scanf("%d", &doctor ); if ( doctors[doctor].empty() ) { printf("EMPTY\n"); } else { printf("%d\n", doctors[doctor].top().id ); doctors[doctor].pop(); } } } } return 0; }
Windows 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#include #include #include #include #include #include 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 S; char s[4]; int Count=1; while ( scanf("%s",s)!=EOF ) { if ( s[0]=='G' ) { if ( S.empty() ) { printf("EMPTY QUEUE!\n"); } else { temp=S.top(); printf("%s %d\n",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
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= #include#include #include #include #include #include #include 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\n",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 6Sample Output
3 3 1 2#include#include #include #include #include #include #include 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\n", small.top() );//输出小顶堆最小数字 while ( b[count+1] == b[count] ) { small.pop();//如果连续输出的话,把这个输出的数字舍弃 printf("%I64d\n", small.top() ); count++; } count++; } //cout< } } return 0; } /*#include #include */#include #include #include using namespace std; #define LL __int64 priority_queue p1 ;//大顶堆在下 priority_queue ,greater > 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\n", 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(0OutputJust output one line for one test case, as described in the Description.
Sample Input2 2 1 5 2 4 2 1 5 6 6Sample Output
11 12#include#include #include #include #include #include #include #include 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 , greater > 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\n", S.top().position ); S.pop(); Count++; } } } return 0; }