字节跳动冬令营网络赛(B.Origami-折纸)

链接: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 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.
pic

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

解法:
考虑两侧的区间,是否全是包含or相离

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
int a[1123456],p[1123456];
int g[1123456];
int main()
{
//	freopen("B.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--) {
		int n=read();
		For(i,n) a[i]=read();
		For(i,n) p[a[i]]=i;
		bool flag=1;
		{
			memset(g,0,sizeof(int)*(n+1));
			For(i,n-1) if(i%2){
				int l=p[i],r=p[i+1];if(l>r) swap(l,r);
				g[l]=r;	
			}
			stack<int> st;
			For(i,n) if(g[i]){
				st.push(g[i]);
			}else if(!st.empty()) {
				if(i==st.top()) st.pop();
			}flag&=st.empty();
		}
		{
			memset(g,0,sizeof(int)*(n+1));
			For(i,n-1) if(i%2==0){
				int l=p[i],r=p[i+1];if(l>r) swap(l,r);
				g[l]=r;	
			}
			stack<int> st;
			For(i,n) if(g[i]){
				st.push(g[i]);
			}else if(!st.empty()) {
				if(i==st.top()) st.pop();
			}flag&=st.empty();
		}
		puts(flag?"Yes":"No");
		
		
	} 
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值