AcWing odd puzzle problem
Description
You must played eight digital game, it is actually carried out in a 3 × 3 grid, the one space and 1 to 8 of these 8 figures just do not leak distributed in this 3 × 3 grid of in.
E.g:
5 2 8 1 3 _ 4 6 7
In the course of the game, you can put on its space, one of the digital down, left, and right direction of exchange (if present).
For example, in the embodiment, a space may be left on, the following digital switching, respectively, into:
5 2 8 5 2 _ 5 2 8 1 _ 3 1 3 8 1 3 7 4 6 7 4 6 7 4 6 _
Odd digital game is an extension of it, in a grid of n × n, where n is an odd number, a space, and ~. 1 \ (n ^ 2 \) -1
This \ (n-2 ^ \) -1 number just do not leak distributed in an n × n grid. Space movement rules and eight digital game the same, in fact, eight digital is a digital n = odd game 3.
Given the situation now two odd digital game, please determine whether there is a way to move a space, so that one situation to another can change the situation.
Input
A plurality of sets of data, for each set of data:
1 a first line of the input integer n, n is an odd number. Next each row n integers n lines, represents the first situation. The next n lines each n
An integer that represents the second situation. - the situation is in each integer 0 \ (^ \ the n-2) , one 1, where 0 represents a space with the remaining value and meaning odd digital game is the same, to ensure the distribution of these integers do not leak.
Output
- For each test, if the situation up to two output TAK, otherwise the output NIE.
Data Size
- 1≤n<500
Sample Input
3 1 2 3 0 4 6 7 5 8 1 2 3 4 5 6 7 8 0 1 0 0
Sample Output
TAK TAK
answer:
- A dazzling look like a road searching questions, but in fact the problem is to find the law.
- For convenience of description, we put this into a one-dimensional two-dimensional graphics drawing graphics called the sequence
- When you move around the space, apparently the same sequence
- When you move up and down the space, it corresponds to a number of front / back number n-1 exchange position
- Found Conclusion: if the two sequences are equal, to reverse some of the same parity.
- Certify that the above conclusion is a large version of mathematical proof, I would not say =. =
- For this problem, n-odd, then it is an even number n-1. Because of changes in the reverse order before certainly not in the reverse order of change , it is assumed that before the change in reverse order of the number is even, the number of reverse change after that (even number - even number = even number) even, assuming that the reverse order of the number of pre-change is odd, then the number of the reverse change (even - odd odd integer) odd number. So for this question, no matter how a sequence of changes in its parity will not change. So do not change it to practice, the parity is determined to only two of the original sequence.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lowbit(x) (x & (-x))
#define N 505 * 505
using namespace std;
int n, cnt, ans1, ans2;
int a[N], b[N], c[N], d[N];
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
int find(int x) {
return lower_bound(c + 1, c + 1 + cnt, x) - c;
}
int ask(int pos)
{
int r = 0;
while(pos >= 1)
{
r += d[pos];
pos -= lowbit(pos);
}
return r;
}
void update(int pos, int val)
{
while(pos <= n * n - 1)
{
d[pos] += val;
pos += lowbit(pos);
}
}
int main()
{
while(scanf("%d", &n) == 1)
{
cnt = 0;
for(int i = 1; i <= n * n; i++)
{
int t = read();
if(t) a[++cnt] = t;
}
cnt = 0;
for(int i = 1; i <= n * n; i++)
{
int t = read();
if(t) b[++cnt] = t;
}
memset(d, 0, sizeof(d));
cnt = 0;
for(int i = 1; i < n * n; i++) c[++cnt] = a[i];
sort(c + 1, c + 1 + cnt);
cnt = unique(c + 1, c + 1 + cnt) - c - 1;
ans1 = 0;
for(int i = 1; i < n * n; i++)
{
int t = find(a[i]);
update(t, 1);
ans1 += i - ask(t);
}
memset(d, 0, sizeof(d));
cnt = 0;
for(int i = 1; i < n * n; i++) c[++cnt] = b[i];
sort(c + 1, c + 1 + cnt);
cnt = unique(c + 1, c + 1 + cnt) - c - 1;
ans2 = 0;
for(int i = 1; i < n * n; i++)
{
int t = find(b[i]);
update(t, 1);
ans2 += i - ask(t);
}
if((ans1 % 2 == 0 && ans2 % 2 == 0) || (ans1 % 2 != 0 && ans2 % 2 != 0)) printf("TAK\n");
else printf("NIE\n");
}
return 0;
}