题面
Given a permutation of length and an array of length .
We call the permutation generating for the array if the array can be obtained from the permutation by applying some number of operations (possibly zero) of the following type:
Choose an index () and perform one of two replacements:
- ;
- .
In other words, in one operation, you can choose two adjacent elements of the array and copy the value of one into the other.
You are required to report whether the permutation is generating for the array .
A permutation of length is an array consisting of distinct integers from to in arbitrary order. For example, is a permutation, but is not a permutation ( appears twice in the array), and is also not a permutation ( but there is in the array).
Input
Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows.
The first line of each test case contains a single integer () — the length of the array and the permutation.
The second line of each test case contains integers () — the elements of the permutation.
The third line of each test case contains integers () — the elements of the array.
It is guaranteed that the sum of across all test cases does not exceed .
Output
For each test case, output “YES” if the permutation is generating for the array , otherwise output “NO”.
You may output each letter in any case (lowercase or uppercase). For example, the strings “yEs”, “yes”, “Yes”, and “YES” will be accepted as a positive answer.
思路
阅读题目,注意到我们无法创造新的数字,只能用存在的数字进行复制替换
因此,在若干次操作后,整个数组会变成一个有很多种重复数字的块
而由题目的“生成排列”的定义可知:这个生成排列本质是从给定的排列 中得到的子序列
因此,我们需要对数组的块进行压缩:
vector<int> b;b.reserve(n);for (int x : a) { if (b.empty() || b.back() != x) b.push_back(x);}压缩之后,我们就需要判断给定的排列是否为得到压缩后的排列 的子序列,如果是则输出 “YES”
在这里,我们使用双指针法,当找到了子序列中的元素时,另一指针 自增,如果最后 ,则说明子序列找到了,使情况得到满足:
int j = 0;for (int x : p) { if (j < (int)b.size() && x == b[j]) ++j;}cout << (j == (int)b.size() ? "YES" : "NO") << '\n';代码
#include <bits/stdc++.h>using namespace std;
int main() { int t; cin >> t; while (t--) { int n; cin >> n;
vector<int> p(n), a(n); for (int i = 0; i < n; ++i) cin >> p[i]; for (int i = 0; i < n; ++i) cin >> a[i];
vector<int> b; b.reserve(n); for (int x : a) { if (b.empty() || b.back() != x) b.push_back(x); }
int j = 0; for (int x : p) { if (j < (int)b.size() && x == b[j]) ++j; }
cout << (j == (int)b.size() ? "YES" : "NO") << '\n'; }
return 0;}