给定一个长度为 n 的数组 a1,a2,…,an。
该数组是一个 1∼n 的排列。
数组的前 n−1 个位置中,部分位置可以进行交换操作,将该位置的元素与后面相邻位置的元素进行互换。
交换操作的次序和次数均不限。
请你判断给定的数组能否通过交换操作变为一个升序数组。
输入格式
第一行包含整数 n。
第二行包含 n 个整数 a1,a2,…,an。
第三行包含一个长度为 n−1 的 01 字符串,第 i 个字符为 1 表示第 i 个位置可以进行交换操作,第 i 个字符为 0 表示第 i 个位置无法进行交换操作。
输出格式
给定的数组可以通过交换操作变为一个升序数组则输出 YES,否则输出 NO。
数据范围
2≤n≤2×100000,
1≤ai≤n, ai 两两不同。
输入样例1:
6
1 2 5 3 4 6
01110
输出样例1:
YES
输入样例2:
6
1 2 5 3 4 6
01010
输出样例2:
NO
思路解析:
我们可以把这个数组去看成几段,由于只有当str[i]=='1' 时数组中对应位置的元素才可以进行互换操作,因此如果数组能够通过交换操作变为一个升序数组则需要str[i]=='0'的位置的元素等于它所对应的下标,并且该元素应当是它和它前面所有元素的最大值
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[200010];
char str[200010];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%s",str+1);
int flag=1;
int t=0;
for(int i=1;i<n;i++)
{
t=max(t,a[i]);
if(str[i]=='0'&&t!=i)
{
flag=0;
break;
}
}
if(flag) puts("YES");
else puts("NO");
return 0;
}