[POJ1753]Flip Game

题目链接:http://poj.org/problem?id=1753

读完题,可以很自然地想到一种搜索。既然每颗只有翻或不翻两种选择,那我们直接列出16颗棋子翻与不翻的所有情况就可以了$ O(2^{16}*判断) $

但是会不会有更科学的解决方法呢?观察可以发现,如果我们确定了第一行,便可以通过翻转第二行的棋子使第一行颜色相同,同理,第三行对第二行,第四行对第三行也是同理。经过以上处理,前三行颜色相同,第四行显然无法在行内自我调整,可以直接判断。所以我们只需要通过搜索确定第一行的四个棋子。

综上我们得出第二种方法,复杂度$ O(2^4*12*判断) $近似$O(2^8*判断)$

事实上这时我初三的代码,现在的我已经弱爆了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int INF = 2147483647;
 6 char G[10][10];
 7 int g[10][10], tmp[10][10], Ans = INF;
 8 void flip(int a, int b){
 9     g[a][b] ^= 1;
10     g[a + 1][b] ^= 1;
11     g[a - 1][b] ^= 1;
12     g[a][b + 1] ^= 1;
13     g[a][b - 1] ^= 1;
14 }
15 int work(int flag, int step){
16     int ans = 0;
17     for (int i = 2; i <= 4; i++){
18         for (int j = 1; j <= 4; j++){
19             if (g[i - 1][j] != flag){
20                 flip(i, j);
21                 ans++;
22             }
23         }
24     }
25     for (int i = 1; i <= 4; i++) 
26         if (g[4][i] != flag)
27             return INF;
28     return ans + step;
29 }
30 void search(int k, int ans){
31     if (k > 4){
32         for (int i = 1; i <= 4; i++)
33             for (int j = 1; j <= 4; j++)
34                 tmp[i][j] = g[i][j];
35         Ans = min(work(0, ans), Ans);
36         for (int i = 1; i <= 4; i++)
37             for (int j = 1; j <= 4; j++)
38                 g[i][j] = tmp[i][j];
39         Ans = min(work(1, ans), Ans);
40         for (int i = 1; i <= 4; i++)
41             for (int j = 1; j <= 4; j++)
42                 g[i][j] = tmp[i][j];
43         return;
44     }
45     search(k + 1, ans);
46     flip(1, k);
47     search(k + 1, ans + 1);
48     flip(1, k);
49 }
50 int main(){
51     for (int i = 1; i <= 4; i++)
52         scanf("%s", G[i] + 1);
53     for (int i = 1; i <= 4; i++) {
54         for (int j = 1; j <= 4; j++) {
55             if (G[i][j] == 'w') g[i][j] = 1;
56             else g[i][j] = 0;
57         }
58     }
59     search(1, 0);
60     if (Ans < INF) printf("%d", Ans);
61     else printf("Impossible");
62     return 0;
63 }

 

posted @ 2020-02-14 22:28  halfrot  阅读(166)  评论(0编辑  收藏  举报