题目描述 给出一个 1∼n 的排列 p,并给出下述两种操作:
显然同一种操作不能连续两次,所以直接交替操作。但是我一开始没想到,用了逆序对个数判断到底进行哪个操作,结果只有 90。
但是后来我又想到了交替的方法,但是还是使用了逆序对判断,还是 90 分。所以我想问一下到底假在哪了(WA 的那个点偷不到数据)。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2000 + 10;
int n, op, dis, ans = 1, a[N], b[N], c[N];
int sum[N];
void update(int i, int x){for(;i<=n*2;i+=i&-i) sum[i] += x;}
int query(int i){
int res = 0;
for(;i;i-=i&-i) res += sum[i];
return res;
}
int getnxd(int *d){
int tot = 0;
memset(sum, 0, sizeof(sum));
for(int i=1;i<=n*2;i++){
tot += i - 1 - query(d[i]);
update(d[i], 1);
}
return tot;
}
int main(){
scanf("%d", &n);
for(int i=1;i<=n*2;i++) scanf("%d", &a[i]);
dis = getnxd(a);
if(!dis) return printf("0\n"), 0;
for(int i=1;i<=n*2;i++) b[i] = c[i] = a[i];
for(int i=1;i<=n;i++) swap(b[i * 2 - 1], b[i * 2]), swap(c[i], c[n + i]);
int cnt1 = getnxd(b), cnt2 = getnxd(c);
if(cnt1 >= cnt2 && cnt2 < dis) for(int i=1;i<=n*2;i++) a[i] = c[i], op = 0;
else if(cnt1 < cnt2 && cnt1 < dis) for(int i=1;i<=n*2;i++) a[i] = b[i], op = 1;
dis = min(cnt1, cnt2);
if(!dis) return printf("1\n"), 0;
while(dis > 0){//连续进行两种操作并没有意义
op ^= 1;
for(int i=1;i<=n*2;i++) b[i] = a[i];
if(op) for(int i=1;i<=n;i++) swap(b[i * 2 - 1], b[i * 2]);
else for(int i=1;i<=n;i++) swap(b[i], b[n + i]);
int cnt = getnxd(b);
if(cnt >= dis) return printf("-1\n"), 0;
dis = cnt, ++ans;
for(int i=1;i<=n*2;i++) a[i] = b[i];
}
printf("%d\n", ans);
return 0;
}