列舉演算法思路訓練 poj2965

2021-10-08 04:46:24 字數 1604 閱讀 4705

這道題相比1753有兩個改變:

一、從小十字變成了大十字(從改變乙個點的上下左右變成了乙個點的整行整列),這個倒是不難做,執行函式稍微改一下就行

二、題目直接讓你輸出改變的點(這道題是special judge),不過我直接把1753的尋找最小步數的思路拿來了,其實只要找到全部為open的乙個解就行了

思路差不多,不多解釋了,直接上**(吐槽一下edge,貼**總是崩潰,google不會崩)

#include

#include

using

namespace std;

char temp[4]

[4];

bool jud[4]

[4];

int temp_min;

int min =

0x7fffffff

;typedef

struct

point;

stackq,t;

void

change

(int n1,

int n2)

void

change_point

(int n1,

int n2)

change

(n1, n2)

;//重複的點

}bool

isok()

return

true;}

void

dfs(

int n1,

int n2)

if(n2 ==4)

if(n1 ==4)

//動if

(!jud[n1]

[n2]);

//吐槽一下,直接push交不上去

t.push

(te)

;//進入佇列

change_point

(n1, n2)

; temp_min++

;dfs

(n1, n2 +1)

; t.

pop();

jud[n1]

[n2]

=false

;change_point

(n1, n2)

;//狀態改回原樣

temp_min--;}

//不動

dfs(n1, n2 +1)

;}void

out(stack

&q)}

intmain()

getchar()

;}dfs(0,

0);if

(min ==

0x7fffffff

) cout <<

"impossible"

<< endl;

//poj1753帶來的,懶得改了,

//順道一提,這道題證明了本題中無論4*4矩陣是2^16個情況任意情況都有使其全部為-的解對應

else

rerurn 0

;}

另外說一下,這裡我直接用棧儲存解,用了後進先出的特點,實際上在dfs用陣列儲存也是可行的,見別人的題解,直接把16當做dfs引數便於在dfs函式中儲存資料

poj 2965 遞迴 列舉

本題與1753思路一樣,區別就在於要記錄位置。deep是當前進行到了哪一步,step是判斷用step步是否可以完成,因此記錄位置只需在change 後做,回溯的時候雖然會說明上一步無效,但不用修改記錄,因為下一次記錄會覆蓋它。include using namespace std bool map ...

再談poj2965(高效演算法)

在列舉分類中已有暴力列舉的方法解這道題。之後在網上看到大神的高效演算法,膜拜之。故copy在此。證明 要使乙個為 的符號變為 必須其相應的行和列的運算元為奇數 可以證明,如果 位置對應的行和列上每乙個位置都進行一次操作,則整個圖只有這一 位置的符號改變,其餘都不會改變.設定乙個4 4的整型陣列,初值...

poj 2965 解題報告

就是對乙個4x4的棋盤進行翻轉,每一次翻轉都將讓同一行和列一起翻轉,直到所有符號都變為 時成功。通過列舉加上深度優先搜尋的方法進行解決,列舉通過行號和列號順序進行,每個位置都有翻轉和不翻轉兩種選擇 通過乙個位置兩次翻轉來回溯 poj 2965 244k 844ms include using nam...