codeforces 920 C Swap Adjacent Elements

本文探讨了一种特殊的数组排序方法,该数组包含从1到n的整数各一次,并且某些相邻元素可以互换。通过分析可交换位置的连续区间并对其进行局部排序来判断整个数组是否能被正确排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ithth element with (i + 1)thth, 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 ithth element with (i + 1)thth (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 a1a1, a2a2, …, anan (1 ≤ aiai ≤ 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 a3a3 and a4a4, and then swap a4a4 and a5a5.


题意:给一个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、付费专栏及课程。

余额充值