题目来源:http://poj.org/problem?id=1737
Rails
Time Limit: 1000MS | Memory Limit: 10000K |
Total Submissions: 37573 | Accepted: 14550 |
Description
There is a famous railway station in PopPushCity. Country there is incredibly hilly. The station was built in last century.Unfortunately, funds were extremely limited that time. It was possible toestablish only a surface track. Moreover, it turned out that the station couldbe only a dead-end one (see picture) and due to lack of available space itcould have only one track.
The local tradition is that every train arriving from the direction A continuesin the direction B with coaches reorganized in some way. Assume that the trainarriving from the direction A has N <= 1000 coaches numbered in increasingorder 1, 2, ..., N. The chief for train reorganizations must know whether it ispossible to marshal coaches continuing in the direction B so that their orderwill be a1, a2, ..., aN. Help him and write a program that decides whether itis possible to get the required order of coaches. You can assume that singlecoaches can be disconnected from the train before they enter the station andthat 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 asnecessary in the station. But once a coach has entered the station it cannotreturn to the track in the direction A and also once it has left the station inthe direction B it cannot return back to the station.
Input
The input consists of blocks of lines. Eachblock except the last describes one train and possibly more requirements forits reorganization. In the first line of the block there is the integer Ndescribed above. In each of the next lines of the block there is a permutationof 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 tothe lines with permutations in the input. A line of the output contains Yes ifit is possible to marshal the coaches in the order required on thecorresponding line of the input. Otherwise it contains No. In addition, thereis 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 theinput.
Sample Input
5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0
SampleOutput
Yes
No
Yes
Source
-----------------------------------------------------
思路
【题意】
给出一个从1~N的升序序列的若干排列,问这些排列能否由该升序序列经过一个栈的出栈入栈操作得到。
【题解】
栈的模拟题。注意到上述过程是可逆的,用2个栈来求排列的逆,如果排列的逆能恢复到原序列,则Yes,否则No.
首先定义一些记号:
1. 数组arr:存放新序列
2. 栈sta:中间结果
3. 栈cont:恢复的序列
恢复的规则就是把从原序列到新序列的操作过程倒过来,并把push和pop互换:
将arr[n-1]入栈sta;
从右到左扫描arr的元素,sta栈顶元素出栈直到sta栈空或arr中当前元素大于sta栈顶元素,sta中出栈的元素按出栈顺序依次入栈cont,然后arr中当前元素入栈sta;
最后sta如果不空的话从栈顶依次出栈并入栈cont直到sta空。
如此一来cont中存放的应该正好是倒序的原序列。
下面用2个例子说明这种可逆性。
Yes的例子
原序列 | 新序列 |
|
1 2 3 4 5 6 | 1 2 3 6 5 4 |
|
原序列到新序列 | 新序列到原序列(倒过来看) | 恢复原序列 |
Push 1 | Pop 1 | Push 1 |
Pop 1 | Push 1 |
|
Push 2 | Pop 2 | Push 2 |
Pop 2 | Push 2 |
|
Push 3 | Pop 3 | Push 3 |
Pop 3 | Push 3 |
|
Push 4 | Pop 4 | Push 4 |
Push 5 | Pop 5 | Push 5 |
Push 6 | Pop 6 | Push 6 |
Pop 6 | Push 6 |
|
Pop 5 | Push 5 |
|
Pop 4 | Push 4 |
|
2. No的例子
原序列 | 新序列 |
|
1 2 3 4 5 | 5 4 1 2 3 |
|
原序列到新序列 | 新序列到原序列 | 恢复原序列 |
Null | Pop 4 | Push 4 |
Null | Pop 5 | Push 5 |
Null | Push 5 |
|
Null | Push 4 |
|
Null | Pop 1 | Push 1 |
Null | Push 1 |
|
Null | Pop 2 | Push 2 |
Null | Push 2 |
|
Null | Pop 3 | Push 3 |
Null | Push 3 |
|
这道题要特别注意的是输出”Yes/No”,而不是通常的”YES/NO”.
-----------------------------------------------------
代码
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
int n;
vector<int> arr;
vector<int> sta;
vector<int> cont;
void test()
{
if (!sta.empty())
{
sta.clear();
}
if (!cont.empty())
{
cont.clear();
}
int i = n-1, elem, poped;
sta.push_back(arr.at(i--));
while (i>=0)
{
elem = arr.at(i--);
while (!sta.empty() && elem < sta.back())
{
poped = sta.back();
sta.pop_back();
cont.push_back(poped);
}
sta.push_back(elem);
}
while (!sta.empty())
{
poped = sta.back();
sta.pop_back();
cont.push_back(poped);
}
i = 1;
for (i=0; i<n; i++)
{
if (cont.at(i) != n-i)
{
cout << "No" << endl;
return;
}
}
cout << "Yes" << endl;
return;
}
int main()
{
#ifndef ONLINE_JUDGE
ifstream fin ("1363.txt");
int i,tmp;
while (fin >> n)
{
if (n==0)
{
break;
}
i = 0;
while (fin >> tmp)
{
if (tmp==0)
{
break;
}
arr.push_back(tmp);
i++;
if (i==n)
{
test();
i = 0;
arr.clear();
}
}
cout << endl;
}
fin.close();
return 0;
#endif
#ifdef ONLINE_JUDGE
int i,tmp;
while (cin >> n)
{
if (n==0)
{
break;
}
i = 0;
while (cin >> tmp)
{
if (tmp==0)
{
break;
}
arr.push_back(tmp);
i++;
if (i==n)
{
test();
i = 0;
arr.clear();
}
}
cout << endl;
}
#endif
}