再談poj2965(高效演算法)

2022-04-28 16:54:06 字數 1184 閱讀 3139

在列舉分類中已有暴力列舉的方法解這道題。之後在網上看到大神的高效演算法,膜拜之。故copy在此。

/*

> 證明:要使乙個為'+'的符號變為'-',必須其相應的行和列的運算元為奇數;可以證明,如果'+'位置對應的行和列上每乙個位置都進行一次操作,則整個圖只有這一'+'位置的符號改變,其餘都不會改變.

> 設定乙個4*4的整型陣列,初值為零,用於記錄每個點的運算元,那麼在每個'+'上的行和列的的位置都加1,得到結果模2(因為乙個點進行偶數次操作的效果和沒進行操作一樣,這就是樓上說的取反的原理),然後計算整型陣列中一的

> 個數即為運算元,一的位置為要操作的位置(其他原來運算元為偶數的因為操作並不發生效果,因此不進行操作)

*********************************

此上證其可以按以上步驟使陣列中值都為『-』

********************************

在上述證明中將所有的行和列的位置都加1後,在將其模2之前,對給定的陣列狀態,將所有的位置操作其所存的運算元個次數,舉例,如果a[i][j]==n,則對(i,j)操作n次,當所有的操作完後,即全為『-』的陣列。

其實就是不模2的操作,作了許多的無用功。

以上的操作次序對結果無影響,如果存在乙個最小的步驟,則此步驟一定在以上操作之中。(簡單說下:因為以上操作已經包含了所有可改變欲改變位置的操作了)

而模2後的操作是去掉了所有無用功之後的操作,此操作同樣包含最小步驟。

但模2後的操作去掉任何乙個或幾個步驟後,都不可能再得到全為『-』的。(此同樣可證明:因為操作次序無影響,先進行最小步驟,得到全為『-』,如果還剩下m步,則在全為『-』的陣列狀態下進行這m步操作後還得到乙個全為

『-』的陣列狀態,此只能是在同乙個位置進行偶數次操作,與前文模2後矛盾,所以m=0),因此模2後的操作即為最小步驟的操作。

*/#include using namespace std;

bool mark[4][4];

char s[4][4];

int main()}}

for(i = 0;i < 4;i++)

for(j = 0;j < 4;j++)

if(mark[i][j] == true)

printf("%d\n",nas);

for(i = 0;i < nas;i++)

return 0;

}

poj 2965 解題報告

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

poj 2965 遞迴 列舉

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

poj2965解題報告

這道題目的思路和 url 的思路一樣。有所不同的是這道題目中還需要輸出搜尋的路徑,於是在unit中加了乙個pre變數以記錄搜尋的路徑,最後通過遞迴呼叫print detail從前往後輸出寬搜的結果。problem 2965 user godfrey90 memory 1992k time 1000m...