奇數碼問題

2022-04-14 13:56:47 字數 1762 閱讀 2931

題目描述

你一定玩過八數碼遊戲,它實際上是在乙個3*3的網格中進行的,1個空格和1~8這8個數字恰好不重不漏地分布在這3*3的網格中。

例如:5 2 8

1 3 _

4 6 7

在遊戲過程中,可以把空格與其上、下、左、右四個方向之一的數字交換(如果存在)。

例如在上例中,空格可與左、上、下面的數字交換,分別變成:

5 2 8       5 2 _      5 2 8

1 _ 3       1 3 8      1 3 7

4 6 7       4 6 7      4 6 _

奇數碼遊戲是它的乙個擴充套件,在乙個n*n的網格中進行,其中n為奇數,1個空格和1~n*n-1這n*n-1個數恰好不重不漏地分布在n*n的網格中。

空格移動的規則與八數碼遊戲相同,實際上,八數碼就是乙個n=3的奇數碼遊戲。

現在給定兩個奇數碼遊戲的局面,請判斷是否存在一種移動空格的方式,使得其中乙個局面可以變化到另乙個局面。

輸入多組資料,對於每組資料:

第1行乙個整數n,n<500,n為奇數。

接下來n行每行n個整數,表示第乙個局面。

接下來n行每行n個整數,表示第二個局面。

局面中每個整數都是0~n*n-1之一,其中用0代表空格,其餘數值與奇數碼遊戲中的意義相同,保證這些整數的分布不重不漏。

輸出對於每組資料,若兩個局面可達,輸出tak,否則輸出nie。

樣例輸入

3

1 2 3

0 4 6

7 5 8

1 2 3

4 5 6

7 8 010

0

樣例輸出
tak

tak

將乙個狀態表示成一維的形式,求出除0之外所有數字的逆序數之和,也就是每個數字前面比它大的數字的個數的和,稱為這個狀態的逆序。

若兩個狀態的逆序奇偶性相同,則可相互到達,否則不可相互到達。

由於原始狀態的逆序為0(偶數),則逆序為偶數的狀態有解。

也就是說,逆序的奇偶將所有的狀態分為了兩個等價類,同乙個等價類中的狀態都可相互到達。

n為偶數時,空格每上下移動一次,奇偶性改變。稱空格位置所在的行到目標空格所在的行步數為空格的距離(不計左右距離),若兩個狀態的可相互到達,則有,兩個狀態的逆序奇偶性相同且空格距離為偶數,或者,逆序奇偶性不同且空格距離為奇數數。否則不能。

也就是說,當此表示式成立時,兩個狀態可相互到達:(狀態1奇偶性==狀態2奇偶性)==(空格距離%2==0)。

要開ll

#include#define ll long long

#define inf 0x3f3f3f3f

using

namespace

std;

const

int n=1e6+5

;int

n;ll a[n];

int lowbit(int

x)void add(int

x)ll sum(

intx)

intmain()

}memset(a,

0,sizeof

(a));

for (int i=1;i<=n;i++)

}if ((ans1%2)==(ans2%2)) printf("

tak\n

"); else printf("

nie\n");

}return0;

}

view code

奇數碼問題

你一定玩過八數碼遊戲,它實際上是在乙個3 3的網格中進行的,1個空格和1 8這8個數字恰好不重不漏地分布在這3 3的網格中。例如 528 13 46 7在遊戲過程中,可以把空格與其上 下 左 右四個方向之一的數字交換 如果存在 例如在上例中,空格可與左 上 下面的數字交換,分別變成 528 52 5...

108 奇數碼問題

類似我們小時候玩過的數字華容道,就是有乙個缺的然後可以移動變成不同的樣子,本題要你解決的是從狀態一能否通過移動變到狀態二。一開始拿到題一看這不就八數碼公升級版嗎,然後改了下八數碼 t了,其實結論做法很簡單,但是如果沒做過類似的題,可能想不到這裡去,這道題需要用奇偶性。奇偶性很神奇,對於一類問題,如果...

問題 N 奇數碼問題

題目描述 你一定玩過八數碼遊戲,它實際上是在乙個3 3的網格中進行的,1個空格和1 8這8個數字恰好不重不漏地分布在這3 3的網格中。例如 5 2 8 1 3 4 6 7 在遊戲過程中,可以把空格與其上 下 左 右四個方向之一的數字交換 如果存在 例如在上例中,空格可與左 上 下面的數字交換,分別變...