poj2893 M×N puzzle

x数码难题有解性判定:

只有必要性证明,没有充分性......

还记得那个naive至极的八数码难题吗?

它回来了!

主要是借助逆序对这一神奇的手段:

考虑把x数码写成一排时的逆序对的奇偶性:

当你左右挪时显然没有影响。

当你上下挪时:列数为奇数则对逆序对奇偶性无影响,为偶数则变动。

然后我们就按照这个莫名其妙的法则A题......666

(注意:此法则不能容许有相同数字。否则奇偶性随机变化,无从下手)

 1 // poj 2893
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 1001;
 6 const int N2 = N * N;
 7 int g[N][N];
 8 typedef long long LL;
 9 struct TreeArray {
10     int a[N2];
11     void clear() {
12         memset(a, 0, sizeof(a));
13         return;
14     }
15     int lowbit(int x) {
16         return x & (-x);
17     }
18     void add(int x, int y) {
19         if(x == 0) {
20             return;
21         }
22         for(int i = x; i < N2; i += lowbit(i)) {
23             a[i] += y;
24         }
25         return;
26     }
27     int getsum(int x) {
28         if(x == 0) {
29             return 0;
30         }
31         int ans = 0;
32         for(int i = x; i > 0; i -= lowbit(i)) {
33             ans += a[i];
34         }
35         return ans;
36     }
37     int ask(int l, int r) {
38         return getsum(r) - getsum(l - 1);
39     }
40 }ta;
41 
42 int main() {
43     int a, b, xx, yy;
44     scanf("%d%d", &a, &b);
45     while(a || b) {
46         ta.clear();
47         for(int i = 1; i <= a; i++) {
48             for(int j = 1; j <= b; j++) {
49                 scanf("%d", &g[i][j]);
50                 if(!g[i][j]) {
51                     xx = i;
52                     yy = j;
53                 }
54             }
55         }
56         // 本题不用离散化
57         LL ans = 0;
58         for(int i = a; i >= 1; i--) {
59             for(int j = b; j >= 1; j--) {
60                 if(g[i][j]) {
61                     ans += ta.getsum(g[i][j] - 1);
62                     ta.add(g[i][j], 1);
63                 }
64             }
65         }
66         if(!(b & 1)) {
67             ans += (a - xx);
68         }
69         if(ans & 1) {
70             printf("NO\n");
71         }
72         else printf("YES\n");
73         scanf("%d%d", &a, &b);
74     }
75     return 0;
76 }
AC代码

 

posted @ 2018-05-06 16:36  garage  阅读(92)  评论(0编辑  收藏  举报