1. 程式人生 > 其它 >CF1558 C. Bottom-Tier Reversals

CF1558 C. Bottom-Tier Reversals

https://codeforces.com/problemset/problem/1558/C

題意:

給出一個長為n(奇數)的排列,要求通過翻轉奇數字首的方式,使排列升序

至多可以做 n*5/2 次翻轉

n為奇數,翻轉不會改變數字所在位置的奇偶性

所以有解的前提是值為奇數的數在奇數位置,偶數在偶數位置

根據次數限制,可以猜測是用5次翻轉使2個歸位

考慮n(奇數)和n-1(偶數)

1、把n翻到第1個位置

2、把n翻到n-1的前面

3、翻轉前n-1所在位置的後一個位置,即把n-1和n分別反轉到第2、3位置

4、翻轉前3個位置

5、翻轉前n個位置

#include<bits/stdc++.h>

using
namespace std; #define N 2023 int n,a[N]; int sum,ans[N*3]; void ok(int x) { ans[++sum]=x; reverse(a+1,a+x+1); } void solve(int x,int y) { for(int i=1;i<=n;i+=2) if(a[i]==y) { ok(i); break; } for(int i=2;i<=n;i+=2) if(a[i]==x) { ok(i
-1); ok(i+1); ok(3); ok(y); break; } } int main() { int T; bool tag; scanf("%d",&T); while(T--) { scanf("%d",&n); tag=true; for(int i=1;i<=n;++i) { scanf("%d",&a[i]);
if((a[i]&1)!=(i&1)) tag=false; } if(!tag) { printf("-1\n"); continue; } sum=0; for(int i=n;i>1;--i) solve(i-1,i); printf("%d\n",sum); for(int i=1;i<=sum;++i) printf("%d ",ans[i]); printf("\n"); } }
作者:xxy 出處:http://www.cnblogs.com/TheRoadToTheGold/ 本文版權歸作者和部落格園共有,轉載請用連結,請勿原文轉載,Thanks♪(・ω・)ノ。