当前位置: 代码迷 >> 综合 >> codeforces 1510K King‘s Task
  详细解决方案

codeforces 1510K King‘s Task

热度:46   发布时间:2023-12-02 23:12:19.0

链接:

https://codeforces.com/problemset/problem/1510/K

题意:

给2*n个数,你可以进行以下两种操作:

  1. Swap p1 and p2, p3 and p4, ..., p2n?1 and p2n.
  2. Swap p1 and pn+1, p2 and pn+2, ..., pn and p2n

问怎么才能用这两种操作,使这2*n个数字变成递增的序列。输出最小值。

本题数据量很小,所以直接暴力,如果连续做两次同一操作序列不变,所以只有121...或212...两种操作顺序。

代码如下:

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<random>
using namespace std;
typedef long long ll;
int n;
int num[2003];
int ori[2003];
bool checkans() {for (int i = 1; i <= 2 * n; i++) {if (num[i] != i) {return false;}}return true;
}
bool check() {for (int i = 1; i <= 2 * n; i++) {if (num[i] != ori[i]) {return 0;}}return 1;
}
void swap1() {for (int i = 1; i <= 2 * n; i+=2) {swap(num[i], num[i + 1]);}
}
void swap2() {for (int i = 1; i <= n; i++) {swap(num[i], num[n+i]);}
}
int main() {cin >> n;for (int i = 1; i <= 2*n; i++) {cin >> num[i];ori[i] = num[i];}ll ans = 2147483647;ll cnt = 0;while (!checkans()) {swap1();cnt++;if (check()) {cnt = 2147483647;break;}if (checkans()) {break;}swap2();cnt++;if (check()) {cnt = 2147483647;break;}}ans = min(ans, cnt);cnt = 0;for (int i = 1; i <= 2 * n; i++) {num[i] = ori[i];}while (!checkans()) {swap2();cnt++;if (check()) {cnt = 2147483647;break;}if (checkans()) {break;}swap1();cnt++;if (check()) {cnt = 2147483647;break;}}ans = min(ans, cnt);if (ans == 2147483647) {cout << -1;}else {cout << ans;}return 0;
}

  相关解决方案