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...