POJ - 3279 枚举 [kuangbin带你飞]专题一
2017-02-13 11:47
330 查看
这题很经典啊,以前也遇到过类似的题--计蒜客 硬币翻转。
不过这题不仅要求翻转次数最少,且翻转方案的字典序也要最小。
解法:二进制枚举第一行的翻转方案,然后处理第二行,如果第二行的k列的上一列是黑色,那么第二行k列必须翻转,因为要保证当前行的上一行全为白色。在第一行确定的情况下,当前翻转一定是最优选择。一样的处理方法直到最后一行,最后检查最后一行是否有黑色,如果有说明当前方案无法成功。
PS:枚举第一行是为了解题方便,枚举任何一行都可以,反正每行都能做出最优解。
AC代码
如有不当之处欢迎指出!
不过这题不仅要求翻转次数最少,且翻转方案的字典序也要最小。
解法:二进制枚举第一行的翻转方案,然后处理第二行,如果第二行的k列的上一列是黑色,那么第二行k列必须翻转,因为要保证当前行的上一行全为白色。在第一行确定的情况下,当前翻转一定是最优选择。一样的处理方法直到最后一行,最后检查最后一行是否有黑色,如果有说明当前方案无法成功。
PS:枚举第一行是为了解题方便,枚举任何一行都可以,反正每行都能做出最优解。
AC代码
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn = 20; int G[maxn][maxn], old[maxn][maxn]; int n, m; const int dx[] = {0,0,-1,1,0}; const int dy[] = {1,-1,0,0,0}; void flip(int x, int y){ for(int i = 0; i < 5; ++i){ int px = x + dx[i], py = y + dy[i]; if(px < 0 || py < 0 || px >= n || py >= m) continue; G[px][py] = 1 - G[px][py]; } } int main(){ while(scanf("%d%d", &n, &m) == 2){ for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j){ scanf("%d", &old[i][j]); } int ans = 1 << 30, a[maxn][maxn]; //memset(a, 1, sizeof(a)); for(int i = 0; i < (1 << m); ++i){ memcpy(G, old, sizeof(G)); int tp = 0, b[maxn][maxn]; memset(b, 0, sizeof(b)); for(int j = 0; j < m; ++j){ if((1 << j) & i) { b[0][j] = 1; ++tp; flip(0, j); } } for(int j = 1; j < n ; ++j) { for(int k = 0; k < m; ++k){ if(G[j - 1][k] == 1){ tp++; b[j][k] = 1; flip(j, k); } } } int flag = 1; for(int j = 0; j < m; ++j){ if(G[n-1][j]) { flag = 0; break; } } if(flag){ int ok = 0; if(tp < ans) ok = 1; else if(tp == ans) { for(int j = 0; j < n; ++j) for(int k = 0; k < m; ++k){ if(b[j][k] < a[j][k]) { ok = 1; j = n, k = m; } else if(b[j][k] > a[j][k]){ j = n, k = m; } } } if(ok) { ans = tp; memcpy(a, b, sizeof(b)); } } } //printf("%d\n", ans); if(ans == 1 << 30) printf("IMPOSSIBLE\n"); else { for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j){ if(j == 0) printf("%d", a[i][j]); else printf(" %d", a[i][j]); } printf("\n"); } } } return 0; }
如有不当之处欢迎指出!
相关文章推荐
- [kuangbin带你飞]专题一 简单搜索D - Fliptile(POJ 3279)
- POJ 3279 Fliptile(kuangbin带你飞 专题一:简单搜索)
- [kuangbin带你飞]专题一 简单搜索-D - Fliptile POJ - 3279
- [kuangbin带你飞]专题一 简单搜索D - Fliptile(POJ 3279)
- [kuangbin带你飞]专题一 简单搜索 E - Find The Multiple poj 1426
- [kuangbin带你飞]专题四 最短路练习 G POJ 1502
- [kuangbin带你飞]专题五 并查集 H POJ 1733
- POJ 2236 A - Wireless Network[kuangbin带你飞]专题五 并查集
- POJ 2421 HDOJ 1102 Constructing Roads(kuangbin带你飞 专题六:最小生成树)
- [kuangbin带你飞]专题1 简单搜索 C - Catch That Cow POJ - 3278
- POJ - 3414 bfs [kuangbin带你飞]专题一
- POJ - 3984 迷宫问题 [kuangbin带你飞]专题一 简单搜索
- [kuangbin带你飞]专题七 线段树 C POJ 3468
- POJ 3126 Prime Path(kuangbin带你飞 专题一:简单搜索)
- [kuangbin带你飞]专题一 简单搜索 G - Shuffle'm Up poj 3087
- [kuangbin带你飞]专题四 最短路练习 H POJ 3660
- [kuangbin带你飞]专题六 最小生成树 G POJ 2349
- [kuangbin带你飞]专题一 简单搜索 A - 棋盘问题(POJ 1321)
- [kuangbin带你飞]专题一 简单搜索 H - Pots poj 3414
- [kuangbin带你飞]专题五 并查集 A POJ 2236