zoukankan      html  css  js  c++  java
  • POJ 3279 Fliptile

    //这道题还是很有意思
    //最开始无从下手但是 可以发现 翻牌和先后顺序无关 ---> 那么只能翻1次或不翻 因为其他情况和1 0 都是重复的
    //那么 如果强行枚举就是2^n
    //这里就没有想到了 ------->降维度的简化
    //确定第一行后 第二行就要把第一行的1都翻为0 才能继续下去 所以第二行事实是确定的
    //以此类推 如果最后一行都为0则成立否则 失败
    //那么只需要枚举第一行的情况 1e4的复杂度 很小

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <queue>
      5 #include <string>
      6 #include <algorithm>
      7 #include <set>
      8 #define READ() freopen("in.txt", "r", stdin);
      9 #define WRITE() freopen("out.txt", "w", stdout);
     10 #define INF 0x3f3f3f3f
     11 
     12 using namespace std;
     13 
     14 int M, N;
     15 int maze[28][28], mazecp[28][28];
     16 int perm[28], num = 0;
     17 set<string> s;
     18 int d[4][2] =
     19 {
     20     -1, 0,
     21     0, 1,
     22     1, 0,
     23     0, -1
     24 };
     25 char operation[28][28];
     26 char ans_operation[28][28];
     27 int tmp_ans = 0, ans = INF;
     28 
     29 bool OK(int x, int y)
     30 {
     31     if (x < 0|| x >= M || y < 0 || y >= N) return false;
     32     return true;
     33 }
     34 
     35 
     36 void dfs(int x)//x表示现在在第几列
     37 {
     38     if (x == N)//最后一列已经决定翻完
     39     {
     40         //先把第一行的翻完
     41         tmp_ans = 0;
     42         for (int i = 0; i < N; i++)
     43         {
     44             if (operation[0][i] == '1')
     45             {
     46                 tmp_ans++;
     47                 mazecp[0][i] += 1;
     48                 for (int p = 0; p < 4; p++)
     49                 {
     50                     int nx = 0+d[p][0], ny = i+d[p][1];
     51                     if (OK(nx, ny))
     52                     {
     53                         mazecp[nx][ny] += 1;
     54                     }
     55                 }
     56             }
     57         }
     58         //第一行确定 其余所有行都确定
     59         for (int i = 1; i < M; i++)
     60         {
     61             for (int j = 0; j < N; j++)
     62             {
     63                 if (mazecp[i-1][j] % 2 == 1)
     64                 {
     65                     operation[i][j] = '1';//那么这一个就要翻
     66                     tmp_ans++;
     67                     mazecp[i][j] += 1;
     68                     for (int p = 0; p < 4; p++)//造成的影响
     69                     {
     70                         int nx = i+d[p][0], ny = j+d[p][1];
     71                         if (OK(nx, ny))
     72                         {
     73                             mazecp[nx][ny] += 1;
     74                         }
     75                     }
     76                 }
     77             }
     78         }
     79         //检查最后一行是否为 都为偶数
     80         bool success = true;
     81         for (int i = 0; i < N; i++)
     82         {
     83             if (mazecp[M-1][i] % 2 == 1)
     84             {
     85                 success = false;
     86                 break;
     87             }
     88         }
     89         if (success)
     90         {
     91             if (tmp_ans < ans)//要先保证翻的次数最少 然后是最小字典序 哎 坑了
     92             {
     93                 ans = tmp_ans;
     94                 for (int i = 0; i < M; i++)
     95                 {
     96                     for (int j = 0; j < N; j++) ans_operation[i][j] = operation[i][j];
     97                 }
     98             }
     99             else if (tmp_ans == ans)
    100             {
    101                 if (strcmp(ans_operation[0], operation[0]) > 0)
    102                 {
    103                     for (int i = 0; i < M; i++)
    104                     for (int j = 0; j < N; j++) ans_operation[i][j] = operation[i][j];
    105                 }
    106             }//成功
    107         }
    108         for (int i = 1; i < M; i++) fill(operation[i], operation[i]+N, '0');//重置操作
    109         for (int i = 0; i < M; i++)
    110         {
    111             for (int j = 0; j < N; j++) mazecp[i][j] = maze[i][j];//重置地图
    112         }
    113         return ;
    114     }
    115     operation[0][x] = '0';
    116     dfs(x+1);
    117     operation[0][x] = '1';
    118     dfs(x+1);
    119     return ;
    120 }
    121 
    122 int main()
    123 {
    124     //READ()
    125     //WRITE()
    126     while(~scanf("%d%d", &M, &N))
    127     {
    128         for (int i = 0; i < M; i++)
    129         {
    130             for (int j = 0; j < N; j++)
    131             {
    132                 scanf("%d", &maze[i][j]);
    133                 mazecp[i][j] = maze[i][j];
    134             }
    135         }
    136         memset(operation, '0', sizeof(operation));
    137         memset(ans_operation, '1', sizeof(ans_operation));
    138         ans = INF;
    139         dfs(0);
    140         if (ans < INF)
    141         {
    142             for (int i = 0; i < M; i++)
    143             {
    144                 for (int j = 0; j < N; j++)
    145                 {
    146                     printf("%c ", ans_operation[i][j]);
    147                 }
    148                 putchar('
    ');
    149             }
    150         }
    151         else printf("IMPOSSIBLE
    ");
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6516001.html
Copyright © 2011-2022 走看看