Origami

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~n,然后随便折,直到不能折,从上向下给你这些数字的顺序。现在任给你一个由1~n的序列,判断是否能折成。

思路:从1-2连一条边放在序列上,2-3连一条放在序列下———,然后判断上是否有交叉的,下是否有交叉。

利用括号匹配去判断,利用相邻数的特点标记括号。

#include <iostream>
#include<algorithm>
#include<stack>
#include<map>
#include<string.h>
#include<stdio.h>
#define mod 1000000009
#define ll long long
using namespace std;
int s[1000006];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
            scanf("%d",&s[i]);
        stack<int>p;
        for(int i=1; i<=n; i++)
        {
            if(n%2==1&&s[i]==n)
                continue;
            int y=(s[i]+1)/2;//从奇数到偶数
            if(p.empty())
                p.push(y);
            else if(p.top()==y)
                p.pop();
            else
                p.push(y);
        }
        if(!p.empty())
            printf("No\n");
        else
        {
            for(int i=1; i<=n; i++)
            {
                if(s[i]==1)
                    continue;
                if(n%2==0&&s[i]==n)
                    continue;
                int y=(s[i])/2;//从偶数到奇数
                if(p.empty())
                    p.push(y);
                else if(p.top()==y)
                    p.pop();
                else
                    p.push(y);
            }
            if(p.empty())
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值