Accept: 81 Submit: 375
Time Limit: 3000 mSec
Problem Description
There are N marbles, which are labeled 1,2,...,N. The N marbles are put in a circular track in an arbitrary order. In the top part of the track there is a “lazy Susan”, which is a tray that can hold exactly 4 marbles. The tray can be rotated, reversing the orientation of the four marbles. The tray can also be moved around the track in both directions. For example, 9 marbles 1, 9, 8, 3, 7, 6, 5, 4, 2 are put in the circular track in clockwise order as shown in the following figure. This figure also shows how the tray is moved and rotated.
Trung wants you to arrange the marbles by moving and rotating the tray so that when listing the marbles from some position in the track in clockwise order, we get (1,2,...,N). Your task is to write a program to tell Trung that either this can be done or not.
Input
The input file consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 100. The following lines describe the data sets. For each data set, the first line contains the integer N (8 ≤ N ≤ 500). The second line describes the initial state of the track. It contains N numbers which are the labels of the marbles when listing in clockwise order.
Output
Sample Input
9
1 9 8 3 7 6 5 4 2
11
1 3 2 4 5 6 7 8 9 10 11
Sample Output
possible
impossible
题解:这种题真的是驾驭不了,简单说一下大致的证明吧:每次翻转四个数,会发现逆序对数的改变一定是偶数,因此如果该序列不管从谁开始都是奇数个逆序对,那就很明显不可能成立,接下来有个结论就是对于环形序列,只有n为奇数且从某一位开始逆序对数是奇数时,从任一位开始的逆序对数才会都是奇数。我们只用看一下偶数为什么一定有偶数个逆序对的序列就好,不妨设从第一位开始有共有奇数个逆序对,第一个数和后面的数构成的二元组共有奇数个,此时选取新的序列从第二位开始,那么原来的第一个数就变成了最后一个,原来的逆序对与非逆序对互换,就有偶数个逆序对了。至于为什么只要逆序对为偶数就一定有解,我也不清楚,请各位大佬指教orz.
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 500 + 10; 6 7 int n, cnt; 8 int num[maxn], tmp[maxn]; 9 10 void merge_sort(int l, int r) { 11 if (l + 1 >= r) return; 12 int m = (l + r) >> 1; 13 merge_sort(l, m); 14 merge_sort(m, r); 15 int p = l, q = m, i = l; 16 while (p < m || q < r) { 17 if (q >= r || (p < m && num[p] < num[q])) tmp[i++] = num[p++]; 18 else { 19 tmp[i++] = num[q++]; 20 cnt += m - p; 21 } 22 } 23 for (int i = l; i < r; i++) { 24 num[i] = tmp[i]; 25 } 26 } 27 28 int main() 29 { 30 //freopen("input.txt", "r", stdin); 31 int iCase; 32 scanf("%d", &iCase); 33 while (iCase--) { 34 scanf("%d", &n); 35 for (int i = 0; i < n; i++) { 36 scanf("%d", &num[i]); 37 } 38 39 cnt = 0; 40 merge_sort(0, n); 41 if ((n & 1) && (cnt & 1)) printf("impossible "); 42 else printf("possible "); 43 } 44 return 0; 45 }