1. 程式人生 > >UVA1620-Lazy Susan(思維+逆序對)

UVA1620-Lazy Susan(思維+逆序對)

一位 clock als con position void sets run merge

Problem UVA1620-Lazy Susan

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 ?gure. This ?gure 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 ?le consists of several data sets. The ?rst line of the input ?le 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 ?rst 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

For each test case, write in one line ‘possible’ if there exists a solution to arrange the marbles. If not so, write ‘impossible’.

技術分享圖片 Sample Input

2
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\n");
42         else printf("possible\n");
43     }
44     return 0;
45 }

UVA1620-Lazy Susan(思維+逆序對)