codeforces 920 C Swap Adjacent Elements

Description
You have an array a consisting of n integers. Each integer from 1 to n appears exactly once in this array.

For some indices i (1 ≤ i ≤ n - 1) it is possible to swap i th t h element with (i + 1) th t h , for other indices it is not possible. You may perform any number of swapping operations any order. There is no limit on the number of times you swap i th t h element with (i + 1) th t h (if the position is not forbidden).

Can you make this array sorted in ascending order performing some sequence of swapping operations?
Input

The first line contains one integer n (2 ≤ n ≤ 200000) — the number of elements in the array.

The second line contains n integers a1 a 1 , a2 a 2 , …, an a n (1 ≤  ai a i  ≤ 200000) — the elements of the array. Each integer from 1 to n appears exactly once.

The third line contains a string of n - 1 characters, each character is either 0 or 1. If i-th character is 1, then you can swap i-th element with (i + 1)-th any number of times, otherwise it is forbidden to swap i-th element with (i + 1)-th.
Output

If it is possible to sort the array in ascending order using any sequence of swaps you are allowed to make, print YES. Otherwise, print NO.
Examples

Input
6
1 2 5 3 4 6
01110
Output
YES
Input
6
1 2 5 3 4 6
01010
Output
NO

Note

In the first example you may swap a3 a 3 and a4 a 4 , and then swap a4 a 4 and a5 a 5 .


题意:给一个1~n的排列,以及第1~n-1哪些位置可以与后面的位置交换
思路:将连续的可交换的位置分别进行排序,处理完后如果整个序列是有序的,那么答案就是可以,如果不是就不行

#include<stdio.h>
#include<algorithm>
using std::sort;

const int _max = 200000 + 5;

int arr[_max];
bool mov[_max];

int main() {
    int n;
    scanf("%d", &n);

    char ch;
    for (int i = 1; i <= n; i++)scanf("%d", &arr[i]);
    for (int i = 1; i <= n-1;) {
            scanf("%c", &ch);
            if (ch == '0') {
                mov[i] = 0;
                ++i;
            }
            else if (ch == '1') {
                mov[i] = 1;
                ++i;
            }
    }
    int cur;
    int l;
    //因为最后的结果应该是1, 2, 3, ...n,所以可以逐个位置检查
    for (cur = 1, l = 1;cur<=n;) {
        if (arr[cur] == cur) { //和排序后的位置对应,不需要改动
        cur++; continue;
        }

        if (arr[cur] != cur) {//不对应,需要改动
            if (mov[cur] == 0)//不可以更改,那么这个位置永远都不能换成对应的数组
            {
                printf("NO");
                return 0;
            }
            else {//把这个位置和后面连续可改动的位置进行排序
                l = cur;
                while (mov[cur])++cur;
                sort(arr + l , arr + cur+1 );
                //检查位置是否一一对应
                for (; l <= cur&&arr[l]==l; ++l);
                if (l <= cur) {//不对应则不可能再有其他改变
                    printf("NO");
                    return 0;
                }
                else {//可行的,继续检查后面的位置
                    ++cur;
                    continue;
                }
            }

        }
    }
    printf("YES");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值