在乙個n*n的矩陣裡,填入0,1,2直到n*n-1,當乙個數的上下左右四個方向中有乙個方向的相鄰的數為0時,該數就可以移動到相應位置。給定乙個初始矩陣和乙個目標矩陣。問能否通過上述操作,將初始矩陣變換為目標矩陣。
這類問題主要是從逆序數奇偶性的角度去考慮,將矩陣內的數按照從左往右從上往下的順序寫成乙個數列(0除外),然後求出這個數列的逆序數(數對兩數為降序排列的數對總數)。對於左右移操作,他們不改變逆序數,對於上下移操作,若n-1為偶數,不改變奇偶性,若為奇數則改變奇偶性。因此若n-1為偶數,只要目標矩陣與初始矩陣逆序數相同既可以實現變換。若n-1為奇數,則初始矩陣與目標矩陣中0的行數差(每移一行奇偶性變化一次)加初始逆序數若與目標逆序數同奇偶,則可以完成轉換。
就這個題而言,還多了一步。由於八個角為死角,別的數移不進去,所以先將裡面的零移出,如果這以後八個死角的值不相等則肯定不能完成轉換。若想等,則轉化為n數碼問題(即上述)。
**如下:
#include#include#includeusing namespace std;
int hash1[8]=;
maphash2;
int s1[8],t1[16],s2[8],t2[16];
void swap(int& a,int& b)
void read(int* a,int* b)
}void deal(int *a,int* b)
}}int main()
}if(!flag)
for(int i=0;i<16;++i)
}for(int i=0;i<16;++i)
if((cnt1+cnt2+r1-r2)%2) printf("y\n");
else printf("n\n");
}return 0;
}
問題 N 奇數碼問題
題目描述 你一定玩過八數碼遊戲,它實際上是在乙個3 3的網格中進行的,1個空格和1 8這8個數字恰好不重不漏地分布在這3 3的網格中。例如 5 2 8 1 3 4 6 7 在遊戲過程中,可以把空格與其上 下 左 右四個方向之一的數字交換 如果存在 例如在上例中,空格可與左 上 下面的數字交換,分別變...
N數碼解的存在問題
推廣二維n n的棋盤 n n的棋盤,n為奇數時,與八數碼問題相同。n為偶數時,空格每上下移動一次,奇偶性改變。稱空格位置所在的行到目標空格所在的行步數為空格的距離 不計左右距離 若兩個狀態的可相互到達,則有,兩個狀態的逆序奇偶性相同且空格距離為偶數,或者,逆序奇偶性不同且空格距離為奇數數。否則不能。...
HDU1043 八數碼問題
include include include using namespace std 通過康托展開來hash 9 有362880 const int maxn 400000 int step maxn int p maxn 2 用於記錄與前面乙個的相對路徑 int d 10 用來統計0到9的階乘 ...