POJ 1753 2965 列舉的藝術

2021-08-28 02:57:10 字數 2677 閱讀 8478

poj 1753 暴力破解

借鑑於: +

(沒有看,物件導向的有點過於複雜) + 自我優化

>原理:每乙個棋子只有兩種狀態,一種是翻過一次,一種是一次也沒有翻過(相當於翻過兩次);因此可以進行列舉,2^16=65536種情況,在可以接受範圍內把所有種類全部列舉一遍。

1.檢查是否列舉結束有兩種辦法:

(優化)1)計數還剩下多少不同的點;

if (cnt == 0 || cnt == 16)

return true;

因此6*10^6也是可以的

2)每次檢查16個點是不是相同顏色的。

遍歷所有點,顏色是不是一致。

2.1)

if (finish())

if (pos >= 16)

return;

如果反過來就會導致錯誤。

2)其他優化:

a)採用乙個整形數記錄所有的資料

00000000 00000000 

b)只列舉第一行如何翻轉和期望達到的黑/白狀態,共計2^4=16種。

之後的每一行為了保持前一行的全黑或全白,只有唯一的翻轉可能。這樣就少掉了很多不必要的搜尋量。

void check(int tmp, bool isblack)

// if (s)

// print();

if (finish() && res > tmp)

res = tmp;

for (int i = 0; i < cnt; ++i)

tran(x[i], y[i]);

}

3.錯誤反思

1)poj無法支援wa查錯;無法支援int_max的功能,很煩。

2)之前我想的是dfs或者bfs,結果想複雜了,就是直接按照pos1-16列舉就行。如果dfs,反而容易搞混頭腦。

3)沒有想到由於第一行的列舉優化。

poj 2956 完全一樣

附上兩個的**:

1753

#include // #include #include using namespace std;

bool a[4][4];

int cnt = 0;

void tran(int x, int y)

void print()

bool finish()

int res = 0xffffff;

void check(int tmp, bool isblack)

// if (s)

// print();

if (finish() && res > tmp)

res = tmp;

for (int i = 0; i < cnt; ++i)

tran(x[i], y[i]);

}void f(int pos, int tmp)

int main()

}f(0, 0);

if (res == 0xffffff)

cout << "impossible\n";

else

cout << res << '\n';

return 0;

}

2956

#include // #include #include #include #include using namespace std;

bool a[4][4];

#define mmax 0xffffff

void tran(int x, int y)

a[x][y] = !a[x][y];

}pairstep[16];

int cnt = 0;

void print()

bool finish()

int res = mmax;

vector> res_step;

void f(int pos, int tmp)

}return;

}

if (pos >= 16)

return;

int x, y;

x = pos % 4;

y = pos / 4;

f(pos + 1, tmp);

tran(x, y);

step[cnt] = pair(x, y);

cnt++;

f(pos + 1, tmp + 1);

tran(x, y);

cnt--;

return;

}int main()

}f(0, 0);

if (res == mmax)

cout << "impossible\n";

else

cout << res << '\n';

// cout << res_step.size() << "sdawefad\n";

for(int i = res_step.size() - 1; i >= 0; --i)

cout << res_step[i].first + 1 << ' ' << res_step[i].second + 1 << '\n';

return 0;

}

POJ 1018 列舉 貪心

題意 有n件商品,每件商品有m個製造商,每個製造商製造的商品有不同的 頻寬和 每件商品必須選乙個製造商,最後的頻寬是所有頻寬中的最小值,價值是所有商品的總 目的是使b p最大,輸出最大的b p的值。思路 由於資料範圍比較小,所以可以列舉。可以求出所有製造商的商品的最大頻寬和最小頻寬,然後列舉在兩者之...

poj 2002 列舉 雜湊

給定n個點,求出這些點一共可以構成多少個正方形。sample input 4 1 00 1 1 10 0 90 0 1 02 0 0 21 2 2 20 1 1 12 1 4 2 5 3 70 0 5 20sample output 1 61可列方程 可以得出 知道兩點求出其餘兩點 x3 node ...

poj1873 列舉 凸包

題意 平面上有n棵樹,現在要砍掉其中的一部分來做成籬笆將剩下的樹包圍起來,現在給出每棵樹的座標 價值和可以製造籬笆的長度,求砍掉最少價值的樹,將剩下的樹包圍起來,當兩種方式的價值相同時,取砍掉樹更少的方式。由於樹棵樹不大於15,可以二進位制列舉情況,求出其它樹構成的凸包的周長即可 include i...