题面
You are given a permutation of length .
You can perform the following operation any number of times (possibly zero):
- Select an index (), and swap and .
For example, when , you can swap and to make it , but you cannot swap and .
Please determine if the sequence can be sorted in increasing order.
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 second line of each test case contains distinct integers ().
It is guaranteed that the sum of over all test cases does not exceed .
Output
If can be sorted in increasing order, output “YES” on a separate line. Otherwise, output “NO” on a separate line.
You can output the answer in any case. For example, the strings “yEs”, “yes”, and “Yes” will also be recognized as positive responses.
思路
注意到题目只允许交换 和 位置的元素,因此,有多条延伸出来的链:
因此,每个交换只能在这一个个链上进行,我们也只需要验证:排序的方式不能跨链条进行,否则无法进行排序
如果对每条链条进行反复交换尝试排序,最终得到的结果是有序的,那么就说明可以排序,否则就是不可以排序
所以在代码的编写上,我们需要首先从每个链条的开头进行:
for (int i = 1; i <= n; i += 2)由于一条链上不可能只有一次交换,所以我们需要多次交换
确定多次交换之后,我们还需要一层循环能够让我们沿着一条链路进行下去:,并比较 如果前者大,就进行交换操作;本质就是一个冒泡排序
但是,如果我们不想要过多的循环次数,让循环次数确定下来呢?
通过我们的分析,一条链的长度设为 ,由于我们知道一条链:
所以很容易得到:
所以可以推得:
因此可以写出如下代码用于确定循环次数:
for (int j = i; j <= n; j *= 2)代码
#include <bits/stdc++.h>
using namespace std;
int main() { int t; cin >> t;
while (t --) { int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i += 2) { for (int j = i; j <= n; j *= 2) { for(int k=i*2;k<=n;k*=2) { if(a[k/2]>a[k]) swap(a[k/2],a[k]); } } }
if(is_sorted(begin(a),end(a))) cout<<"YES\n"; else cout<<"NO\n"; }}