# acm/icpc live archive regional 1998 europe central problem d, spoj 45 commedia dell arte

So called commedia dell' arte is a theater genre first played at Italy in the beginning of the sixteenth century. It was inspired with the Roman Theater. The play had no fixed script and the actors (also called performers) had to improvise a lot. There were only a simple directions by the author like "enter the stage and make something funny" or everyone comes on stage and everything is resolved happily". You can see it might be very interesting to play the commedia dell' arte. Therefore the ACM want to put a new play on a stage, which was completely unknown before. The main hero has a puzzle that takes a very important role in the play and gives an opportunity of many improvisations.

The puzzle is the worldwide known Lloyd's Fifteen Puzzle. ACM wants to make the play more interesting so they want to replace the standard" puzzle with a three-dimensional one. The puzzle consists of a cube containing M3 slots. Each slot except one contains a cubic tile (one position is free). The tiles are numbered from 1 to M3-1. The goal of the puzzle is to get the original ordering of the tiles after they have been randomly reshuffled. The only allowed moves are sliding a neighbouring tile into the free position along one of the three principal directions. Original configuration is when slot with coordinates (x,y,z) from contains tile number z.M2+y.M+x+1 and slot (M-1,M-1,M-1) is free.

Your are to write a program to determine whether it is possible to solve the puzzle or not.

## Input

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. The first line of each case contains only one integer M. It is the size of 3D puzzle cube. Then follow M lines, each contains exactly M2numbers on the tiles for one layer. First is the layer on the top of the cube and the last one on the bottom. In each layer numbers are arranged from the left top corner linewise to the right bottom corner of the layer. In other words, slot with coordinates (x,y,z) is described by the (x+M.y+1)-th number on the (z+1)-th line. Numbers are separated by space. Number 0 means free position.

## Output

For each case, print exactly one line. If the original configuration can be reached by sliding the tiles, print the sentence Puzzle can be solved.'. Otherwise, print the sentence Puzzle is unsolvable.'.

## Sample Input

2
2
1 2 3 4
5 7 6 0
2
2 1 3 5
4 6 0 7


## Sample Output

Puzzle is unsolvable.
Puzzle can be solved.


Miguel A. Revilla
2000-02-15

#include <cstdio>
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <algorithm>

#define SZ_MAX (100 * 100 * 100)

long long MergeSort (int a [SZ_MAX], int sz) {
if (sz <= 1) {
return 0;
}
int *buf = (int *) malloc (sz * sizeof (int));
memcpy (buf, a, sz * sizeof (int));

int *left = buf;
int *right = buf + sz / 2;

long long rev = MergeSort (left, sz / 2) + MergeSort (right, sz - sz / 2);

int i = 0;
int k = 0;
int m = 0;

while (m < sz) {
if (k >= sz - sz / 2 || (i < sz / 2 && left [i] <= right [k])) {
a [m++] = left [i++];
} else {
assert (i >= sz / 2 || left [i] > right [k]);
assert (k < sz - sz / 2);
a [m++] = right [k++];
rev += sz / 2 - i;
}
}
assert (i + k == m);

free (buf);

return rev;
}

int CubRoot (int n) {
for (int i=0; i<=n; ++i) {
if (i * i * i == n) {
return i;
}
}
assert (false);
}

long long Dist (int a [SZ_MAX], int sz) {
long long dist = 0;
long long n = CubRoot (sz);
for (long long i=0; i<sz; ++i) {
if (a[i] == 0) {
continue;
}
long long t = a[i] - 1;
dist += std::abs (t / (n * n) - i / (n * n));
dist += std::abs (t / n % n - i / n % n);
dist += std::abs (t % n - i % n);
}
return dist;
}

int main () {
int cs;
scanf ("%d", &cs);
while (cs--) {
int n;
scanf ("%d", &n);
n = n * n * n;
static int a [SZ_MAX];
for (int i=0; i<n; ++i) {
scanf ("%d", &a[i]);
}

bool isSolvable;

if (n % 2 == 0) {
long long dist = Dist (a, n);

// replace the zero with n
int zero = -1;
while (++zero < n && a [zero]) {}
assert (zero < n);
a [zero] = n;

// get reverse order
long long rev = MergeSort (a, n);

isSolvable = ((dist + rev) % 2 == 0);
} else {
// put the zero to the end
int zero = -1;
while (++zero < n && a [zero]) {}
assert (zero < n);
while (++zero < n) {
std::swap (a [zero - 1], a [zero]);
}

// get reverse order
long long rev = MergeSort (a, n - 1);

isSolvable = (rev % 2 == 0);
}
printf (isSolvable ? "Puzzle can be solved.\n" : "Puzzle is unsolvable.\n");
}
return 0;
}


#### 2017-2018 ACM-ICPC Southeast Regional Contest (Div. 1) H.Security Badges 区间双重合

2017-12-11 15:22:47

#### 2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15) A题Promotions

2017-03-30 21:37:22

#### 2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15)训练总结【7/10】

2017-08-16 19:15:39

#### 2005-2006 ACM-ICPC East Central North America Regional Contest (ECNA 2005) G.Swamp Things

2015-08-18 18:39:38

#### 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)题解

2016-09-09 00:35:59

#### 2014-2015 ACM-ICPC East Central North America Regional Contest (ECNA 2014)

2015-05-21 12:03:12

#### 2005-2006 ACM-ICPC East Central North America Regional Contest (ECNA 2005) F.Square Count

2015-08-18 18:45:56

#### 2017 ACM ICPC Asia Regional - Daejeon Programming Constest

2018-03-31 20:59:40

#### 「备战PKUWC2018」2017-2018 ACM-ICPC, Asia Daejeon Regional Contest

2018-01-16 21:20:50

#### 2008 ACM ICPC South Central USA Regional Programming Contest

2009年06月09日 1.06MB 下载