链接:https://ac.nowcoder.com/acm/contest/296/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
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 pi to the right. After this query the leftmost part of the paper with dimensions 1 x pi must be above the rightmost part of the paper with dimensions ).
- Fold the sheet of paper at position pi to 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
题目大意:
初始的时候有一张纸,可以从左边往右边折叠,或者从右边往左边折叠
每次折叠的长度不能超过现有宽度,最后折叠到长度为1
从上往下看会有一个1−n的排列1−n的排列,现在给出这个排列
问这个排列是否是合法折叠出来的
题解:
将最后的结果从1到n连线,1连接2在a边,2连接3在b边,3连接4在a边,4连接5在b边……以此类推,保证两边都不存在相交的线,也就可以转化成给出一串区间,要求区间之间可以重叠,相离,但不能相交。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int s[1000010];
int a[1000010];
int q[1000010];
pair<int ,int > pl[500010];
pair<int ,int > pz[500010];
pair<int ,int > py[500010];
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
s[a[i]]=i;
}
for(int i=1;i<=n;i++)
{
if(a[i]!=n){
q[a[i]]=s[a[i]+1];
}
else{
q[a[i]]=i;
}
}
int zz=1,yy=1;
for(int i=1;i<n;i++)
{
if(i%2)
pz[zz++]=make_pair(min(s[i],q[i]),max(s[i],q[i]));
else
py[yy++]=make_pair(min(s[i],q[i]),max(s[i],q[i]));
}
sort(pz+1,pz+zz);
sort(py+1,py+yy);
bool flag=true;
int xx=1;
pl[xx].first=pz[1].first;
pl[xx].second=pz[1].second;
for(int i=2;i<zz;i++)
{
bool flagx=true;
while(flagx)
{
if(pl[xx].first<pz[i].first && pl[xx].second<pz[i].second && pl[xx].second>pz[i].first){
flag=false;
flagx=false;
}
else if(pl[xx].second>pz[i].second){
pl[++xx].first=pz[i].first;
pl[xx].second=pz[i].second;
flagx=false;
}
else{
pl[xx].first=pz[i].first;
pl[xx].second=pz[i].second;
xx--;
if(xx==0)
{
xx=1;
flagx=false;
}
}
}
}
if(flag)
{
int xx=1;
pl[xx].first=py[1].first;
pl[xx].second=py[1].second;
for(int i=2;i<yy;i++)
{
bool flagx=true;
while(flagx)
{
if(pl[xx].first<py[i].first && pl[xx].second<py[i].second && pl[xx].second>py[i].first){
flag=false;
flagx=false;
}
else if(pl[xx].second>py[i].second){
pl[++xx].first=py[i].first;
pl[xx].second=py[i].second;
flagx=false;
}
else{
pl[xx].first=py[i].first;
pl[xx].second=py[i].second;
xx--;
if(xx==0)
{
xx=1;
flagx=false;
}
}
}
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}