P14972 『GTOI - 2C』Fliping题解
P14972 『GTOI - 2C』Fliping
题目描述
给出一个 1∼n1\sim n1∼n 的排列 aaa,请问能否通过不超过 300030003000 次操作使数组 aaa 单调递增。
对于每次操作,你可以翻转一个长度至少为 3\bm33 的区间。
其中,“翻转”指的是:例如数组 a={5,4,3,2,1}a = \{5,4,3,2,1\}a={5,4,3,2,1} ,翻转区间是 [2,4][2,4][2,4] 的话,结果是 a={5,2,3,4,1}a = \{5,2,3,4,1\}a={5,2,3,4,1}。
如果可以,输出一种构造方案,具体请参考 【输出格式】。
如果不可以,输出 -1。
输入格式
输入共两行。
第一行,一个正整数 nnn。
第二行,一个 1∼n1\sim n1∼n 的排列 aaa。
输出格式
如果存在构造方案:
- 输出一个非负整数 mmm 表示总共需要操作的次数。
- 然后输出 mmm 行,每行两个正整数 l,rl,rl,r 表示每次翻转的区间 [l,r][l,r][l,r]。
本题使用 Special Judge ,若有多组构造方案,任意输出一组即可。
如果不存在构造方案,输出 -1 即可。
输入输出样例 #1
输入 #1
5
2 5 4 3 1
输出 #1
3
1 4
1 3
1 5
说明/提示
【数据范围】
本题采用捆绑测试。
对于 100%100\%100% 的数据,保证 1≤n≤20001\leq n\leq 20001≤n≤2000,{a}\{a\}{a} 为 1∼n1\sim n1∼n 的排列。
| Subtask\text{Subtask}Subtask | n≤n \leqn≤ | 特殊性质 | 分数 |
|---|---|---|---|
| 111 | 777 | 无 | 202020 |
| 222 | 505050 | ^ | 101010 |
| 333 | 100010001000 | ^ | 101010 |
| 444 | 150015001500 | ^ | 101010 |
| 555 | 200020002000 | 保证 aia_iai 随机生成 | 101010 |
| 666 | ^ | 保证 ai≡i(mod2)a_i\equiv i\pmod 2ai≡i(mod2) | 202020 |
| 777 | ^ | 无 | 202020 |
思路
直接每次行则立刻转,否则转最后再转即可,然后<=5时特判一下。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,a[2005];
struct one{
long long l,r;
};
vector<one> v;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1,k;i<=n;i++){
for(int j=i;j<=n;j++){
if(a[j]==i){
k=j;
break;
}
}
if(i==k){
continue;
}
if(k-i>=2){
v.push_back({i,k});
for(int j=i;j<=(i+k)/2;j++){
swap(a[j],a[i+k-j]);
}
}
else if(n-k>=2){
v.push_back({k,n});
for(int j=k;j<=(k+n)/2;j++){
swap(a[j],a[k+n-j]);
}
v.push_back({i,n});
for(int j=i;j<=(i+n)/2;j++){
swap(a[j],a[i+n-j]);
}
}
else{
if(k==n){
if(n<=4){
cout<<-1<<endl;
return 0;
}
else{
v.push_back({n-4,n-1});
v.push_back({n-3,n-1});
v.push_back({n-4,n});
v.push_back({n-4,n-1});
cout<<v.size()<<endl;
for(int j=0;j<v.size();j++){
cout<<v[j].l<<" "<<v[j].r<<endl;
}
return 0;
}
}
else{
if(a[n]==n){
if(n<=5){
cout<<-1<<endl;
return 0;
}
else{
n--;
v.push_back({n-4,n-1});
v.push_back({n-3,n-1});
v.push_back({n-4,n});
v.push_back({n-4,n-1});
cout<<v.size()<<endl;
for(int j=0;j<v.size();j++){
cout<<v[j].l<<" "<<v[j].r<<endl;
}
return 0;
}
}
else{
if(n<=5){
cout<<-1<<endl;
return 0;
}
else{
v.push_back({n-2,n});
n--;
v.push_back({n-4,n-1});
v.push_back({n-3,n-1});
v.push_back({n-4,n});
v.push_back({n-4,n-1});
cout<<v.size()<<endl;
for(int j=0;j<v.size();j++){
cout<<v[j].l<<" "<<v[j].r<<endl;
}
return 0;
}
}
}
}
}
cout<<v.size()<<endl;
for(int j=0;j<v.size();j++){
cout<<v[j].l<<" "<<v[j].r<<endl;
}
return 0;
}

浙公网安备 33010602011771号