链接:https://ac.nowcoder.com/acm/contest/296/B
来源:牛客网
题目描述
Chiaki has a very big sheet of paper. This sheet has a form of rectangle with dimensions 1 x n and numbers from 1 to n was written on each small 1 x 1 grid. Chiaki would like to fold the paper using the following operations:
- Fold the sheet of paper at position pito the right. After this query the leftmost part of the paper with dimensions 1 x pimust be above the rightmost part of the paper with dimensions ).
- Fold the sheet of paper at position pito the left. After this query the rightmost part of the paper with dimensions ) must be above the leftmost part of the paper with dimensions 1 x pi.
After performing the above operations several times, the sheet of paper has dimensions 1 x 1. If we write down the number on each grid from top to bottom, we will have a permutation of n.
Now given a permutation of n, Chiaki would like to know whether it is possible to obtain the permutation using the above operations.
输入描述:
There are multiple test cases. The first line of the input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 106), indicating the length of the paper.
The second line contains n integers a1, a2, ..., an, which is a permutation of n, indicating the integers marked in the grids of the resulting sheet of paper from top to bottom.
It's guaranteed that the sum of n in all test cases will not exceed 106.
输出描述:
For each test case output one line. If it's possible to obtain the permutation, output ``Yes'' (without the quotes), otherwise output ``No'' (without the quotes).
示例1
输入
复制
3
4
2 1 4 3
7
2 5 4 3 6 1 7
4
1 3 2 4
输出
复制
Yes
Yes
No
题意:一段1xn的纸条,折纸,最后折成1x1,给定一个从上到下的序列,问能不能折成这样。
分析:
折纸的过程就是形成区间的过程,1-n本来是连着的,我们从1开始,连线到2,然后从2的另一端继续连到3......直到n
这样就构成了左右两边两个区间序列,这道题唯一的限制就是纸张不能穿过去,也就是说同一方向上的区间不能相交
然后就是分两块判断有序区间有没有相交
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <cstring>
#define MP make_pair
#define PB push_back
using namespace std;
#define maxn 1000005
int pos[maxn];
#define PIN pair<int,int>
vector<PIN>vec1;
vector<PIN>vec2;
void solve()
{
stack<PIN>s;
for(int i=0;i<vec1.size();i++)
{
while (!s.empty())//记录一个包含关系的区间集合
{
PIN t;
t = s.top();
if(vec1[i].second<t.second)//如果当前区间被前一个区间包含,就把他放在stack里
{
break;
}
if(vec1[i].second>t.second&&vec1[i].first<t.second)//相交 非法
{
cout<<"No"<<endl;
return;
}
s.pop();
}
s.push(vec1[i]);
}
while(!s.empty())s.pop();
for(int i=0;i<vec2.size();i++)
{
while (!s.empty())//记录一个包含关系的区间集合
{
PIN t;
t = s.top();
if(vec2[i].second<t.second)//如果当前区间被前一个区间包含,就把他放在stack里
{
break;
}
if(vec2[i].second>t.second&&vec2[i].first<t.second)//相交 非法
{
cout<<"No"<<endl;
return;
}
s.pop();
}
s.push(vec2[i]);
}
cout<<"Yes"<<endl;
return;
}
bool cmp(PIN a,PIN b)
{
return a.first<b.first;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
int n;
while(t--)
{
vec1.clear();
vec2.clear();
int tem;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>tem;
pos[tem]=i;
}
int minn;
int maxx;
for(int i=1;i<n;i++)
{
maxx=max(pos[i],pos[i+1]);
minn=min(pos[i],pos[i+1]);
if(i%2==1)
{
vec1.PB(MP(minn,maxx));
}
else
{
vec2.PB(MP(minn,maxx));
}
}
sort(vec1.begin(),vec1.end(),cmp);
sort(vec2.begin(),vec2.end(),cmp);
solve();
}
}