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 }
  • 相关阅读:
    rowkey设计原则和方法
    ubuntu安装及使用
    sqoop数据迁移
    Hive 自定义UDF操作步骤
    hive之数据导入导出
    MySQL优化
    MongoDB、Redis、elasticSearch、hbase的对比
    数据库基本操作
    count(*) 和 count(1)和count(列名)区别
    BigDecimal的运算——加减乘除
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/6516001.html
Copyright © 2011-2022 走看看