怎麼還原這個九宮格拼圖,怎麼還原這個九宮格拼圖

2021-03-03 21:08:17 字數 6513 閱讀 5270

1樓:匿名使用者

把右下角這個移到中間去

2樓:卡列寧

我不會啊啊啊啊啊啊啊啊

9宮格拼圖怎麼還原?

3樓:匿名使用者

右下移,中上移,坐右移,中上左移,左上下移。

九宮格拼圖這個怎麼移

4樓:bigbig大汪汪

將完整的圖分為九格從上打下依次是123 456 789 ,則打亂後的圖的編碼從上到下為542 716 38

8向下移 3下 7右 1上 4右 5下 1左 4上 3左 8上 6右 3下 5右 2上 3左 6左

5樓:寂寞丶love之歌

上下下右上左..............贊乙個

誰知道怎麼解開這個九宮格拼圖

6樓:藪貓

右下角那一塊左移乙個位置,那麼明顯的胸部你給搞偏了!

然後本來是最下方左二的那一塊你看是在右起第一列最下面還是中間合適,注意把頭髮上的緞帶和手機連線完整就行。

九宮格拼圖·求此問題解法~~思路~**都可~~就是關於其還原演算法的·急~**等~多謝哈

7樓:匿名使用者

在乙個3×3的九宮中有1-8這8個數及乙個空格隨機的擺放在其中的格仔裡,如圖1-1所示。現在要求實現這個問題:將其調整為如圖1-1右圖所示的形式。

調整的規則是:每次只能將與空格(上、下、或左、右)相鄰的乙個數字平移到空格中。試程式設計實現這一問題的求解。

(圖1-1)

二、題目分析:

這是人工智慧中的經典難題之一,問題是在3×3方格棋盤中,放8格數,剩下的沒有放到的為空,每次移動只能是和相鄰的空格交換數。程式自動產生問題的初始狀態,通過一系列交換動作將其轉換成目標排列(如下圖1-2到圖1-3的轉換)。

(圖1-2) (圖1-3)

該問題中,程式產生的隨機排列轉換成目標共有兩種可能,而且這兩種不可能同時成立,也就是奇數排列和偶數排列。可以把乙個隨機排列的陣列從左到右從上到下用乙個一維陣列表示,如上圖1-2我們就可以表示成{8,7,1,5,2,6,3,4,0}其中0代表空格。

在這個陣列中我們首先計算它能夠重排列出來的結果,公式就是:

∑(f(x))=y,其中f(x)

是乙個數前面比這個數小的數的個數,y為奇數和偶數時各有一種解法。(八數碼問題是否有解的判定 )

上面的陣列可以解出它的結果。

f(8)=0;

f(7)=0;

f(1)=0;

f(5)=1;

f(2)=1;

f(6)=3;

f(3)=2;

f(4)=3;

y=0+0+0+1+1+3+2+3=10

y=10是偶數,所以其重排列就是如圖1-3的結果,如果加起來的結果是奇數重排的結果就是如圖1-1最右邊的排法。

三、演算法分析

求解方法就是交換空格(0)位置,直至到達目標位置為止。圖形表示就是:

(圖3-1)

要想得到最優的就需要使用廣度優先搜尋,九宮的所以排列有9!種,也就是362880種排法,資料量是非常大的,使用廣度搜尋,需要記住每乙個結點的排列形式,要是用陣列記錄的話會佔用很多的記憶體,可以把資料進行適當的壓縮。使用dword形式儲存,壓縮形式是每個數字用3位表示,這樣就是3×9=27個位元組,由於8的二進位制表示形式1000,不能用3位表示,使用了乙個小技巧就是將8表示為000,然後用多出來的5個字表示8所在的位置,就可以用dword表示了。

用移位和或操作將資料逐個移入,比乘法速度要快點。定義了幾個結果來儲存遍歷到了結果和搜尋完成後儲存最優路徑。

類結構如下:

class **inegird

;struct scanbuf

;struct pathlist

;private:

placelist *m_pplacelist;

scanbuf *m_pscanbuf;

rect m_rresetbutton;

rect m_rautobutton;

public:

int m_ipathsize;

clock_t m_itime;

uint m_istepcount;

unsigned char m_itargetchess[9];

unsigned char m_ichess[9];

hwnd m_hclientwin;

pathlist *m_ppathlist;

bool m_bautorun;

private:

inline bool addtree(dword place , placelist*& parent);

void freetree(placelist*& parent);

inline void arraytodword(unsigned char *array , dword & data);

inline void dwordtoarray(dword data , unsigned char *array);

inline bool movechess(unsigned char *array , int way);

bool estimateuncoil(unsigned char *array);

void getpath(uint depth);

public:

void movechess(int way);

bool ***putefeel();

void activeshaw(hwnd hview);

void drawgird(hdc hdc , rect clientrect);

void drawchess(hdc hdc , rect clientrect);

void reset();

void onbutton(point pnt , hwnd hview);

public:

**inegird();

~**inegird();

};計算隨機隨機數組使用了vector模板用random_shuffle(,)函式來打亂陣列資料,並計算目標結果是什麼。**:

void **inegird::reset()

if (!estimateuncoil(m_ichess))

;memcpy(m_itargetchess , array , 9);

}else

;memcpy(m_itargetchess , array , 9);

}m_istepcount = 0;

}資料壓縮函式實現:

inline void **inegird::arraytodword(unsigned char *array , dword& data)

}array[night] = 0;

data = 0;

data = (dword)((dword)array[0] << 29 | (dword)array[1] << 26 |

(dword)array[2] << 23 | (dword)array[3] << 20 |

(dword)array[4] << 17 | (dword)array[5] << 14 |

(dword)array[6] << 11 | (dword)array[7] << 8 |

(dword)array[8] << 5 | night);

array[night] = 8;

}解壓縮時跟壓縮正好相反,解壓**:

inline void **inegird::dwordtoarray(dword data , unsigned char *array)

chtem = (unsigned char)(data & 0x0000001f);

array[chtem] = 8;

}由於可擴充套件的資料量非常的大,加上在儲存的時候使用的是dword型別,將每一步資料都記錄在乙個排序二叉樹中,按從小到大從左到有的排列,搜尋的時候跟每次搜尋將近萬次的形式比較快幾乎是n次方倍,把幾個在迴圈中用到的函式宣告為內聯函式,並在插入的時候同時搜尋插入的資料會不會在樹中有重複來加快總體速度。二叉樹插入**:

inline bool **inegird::addtree(dword place , placelist*& parent)

if (parent->place == place)

return false;

if (parent->place > place)

return addtree(place , parent->left);

}計算結果是奇數排列還是偶數排列的**:

bool **inegird::estimateuncoil(unsigned char *array)}}

if (sun % 2 == 0)

return true;

else

return false;

}移動到空格位的**比較簡單,只要計算是否會移動到框外面就可以了,並在移動的時候順便計算一下是不是已經是目標結果,這是用來給使用者手工移動是給與提示用的,**:

inline bool **inegird::movechess(unsigned char *array , int way)

point pnt;

pnt.x = zero % 3;

pnt.y = int(zero / 3);

switch(way)

break;

case 1 : //down

if (pnt.y - 1 > -1)

break;

case 2 : //left

if (pnt.x + 1 < 3)

break;

case 3 : //right

if (pnt.x - 1 > -1)

break;

}if (moveok && !m_bautorun)

}return moveok;

}在進行廣度搜尋時候,將父結點所在的陣列索引記錄在子結點中了,所以得到目標排列的時候,只要從子結點逆向搜尋就可以得到最優搜尋路徑了。用變數m_ipathsize來記錄總步數,具體函式**:

void **inegird::getpath(uint depth)

m_ppathlist = new pathlist[maxpos];

parentid = m_pscanbuf[depth].scanid;

dwordtoarray(m_pscanbuf[depth].place , m_ppathlist[++now].path);

while(parentid != -1)

dwordtoarray(m_pscanbuf[parentid].place , m_ppathlist[++now].path);

parentid = m_pscanbuf[parentid].scanid;

}m_ipathsize = now;

}動態排列的演示函式最簡單了,為了讓主窗體有及時重新整理的機會,啟動了乙個執行緒在需要主窗體重新整理的時候,用slee(uint)函式來暫停一下執行緒就可以了。**:

unsigned __stdcall movechessthread(lpvoid pparam)

char msg[100];

sprintf(msg , "^_^ ! 搞定了!\r\n計算步驟用時%d毫秒" , pgird->m_itime);

messagebox(null , msg , "~_~" , 0);

pgird->m_bautorun = false;

return 0l;

}最後介紹一下搜尋函式的原理,首先得到源陣列,將其轉換成dword型,與目標比較,如果相同完成,不同就交換一下資料和空格位置,加入二叉樹,搜尋下乙個結果,直到沒有步可走了,在搜尋剛剛搜尋到的位置的子位置,這樣直到找到目標結果為止,函式:

bool **inegird::***putefeel()

if (m_pscanbuf != null)

m_pscanbuf = new scanbuf[maxsize];

addtree(fountain ,m_pplacelist);

m_pscanbuf[ 0 ].place = fountain;

m_pscanbuf[ 0 ].scanid = -1;

clock_t tim = clock();

while(parentid < maxsize && child < maxsize)

child ++;}}

} // for i

parentid++;

}m_itime = clock() - tim;

freetree(m_pplacelist);

delete m_pscanbuf;

m_pscanbuf = null;

return false;

}重要函式的介紹結束;下面是程式的執行結果和運算結果:

誰知道怎麼解開這個九宮格拼圖,九宮格的拼圖怎麼解開求助啊

右下角那一塊左移乙個位置,那麼明顯的胸部你給搞偏了!然後本來是最下方左二的那一塊你看是在右起第一列最下面還是中間合適,注意把頭髮上的緞帶和手機連線完整就行。九宮格拼圖有解的條件?我也設計過這個的flash動畫,只要讓12345678這8個數字任意兩個不同數字交換,如果交換偶數次就一定能行。九宮格的拼...

九宮格的意思九宮格是什麼意思

九宮格 是我國書法史上臨帖寫仿的一種界格,又叫 九方格 另外也指一種手機鍵盤布局,是相對於全鍵盤而言。九宮格 也是一種很受人們喜愛的遊戲。1 書法 九宮格 九宮格 是我國書法史上臨帖寫仿的一種界格,又叫 九方格 即在紙上畫出若干大方框,再於每個方框內分出九個小方格,以便對照法帖範字的筆畫部位進行練字...

求解答這個九宮格數獨,1一一9九宮格數獨口訣精編版

看不清楚可以問我,但希望給個採納 數獨是源自18世紀瑞士的一種數學遊戲。是一種運用紙 筆進行演算的邏輯遊戲。玩家需要根據9 9盤面上的已知數字,推理出所有剩餘空格的數字,並滿足每一行 每一列 每乙個粗線宮 3 3 內的數字均含1 9,不重複。數獨盤面是個九宮,每一宮又分為九個小格。在這八十一格中給出...