zoukankan      html  css  js  c++  java
  • POJ 3279 Filptile dfs

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

     大意:给出一块n*m的棋盘。里面放满了棋子。有1和0两种状态。给出初始状态,翻动的时候会把当前位置和当前位置的上下左右共五个位置翻动。现在问最小步骤的翻动方案。步  骤数相同时按照字典序输出。(输出按照n*m的形式输出每个格子的翻动次数)

     其中!字典序的意思是每行首尾相接连成的字符串排序。亲测和顺序有关。

     改了字典序之后,测试无数次找到神奇的bug就是string字符串的初始化。2333。

     其实感觉不是dfs,至少对我来说就是一个二进制枚举+search的过程。不如说是暴力search?

     附代码,已AC。

      1 // 我想说我不会这个题。开始的时候是感觉每个格子搜一遍的超暴力dfs 我是可以的。然后呢。一定会超时的。恩。
      2 // 然后先确定第一行的操作就可以确定第二行的操作了?恩。因为我第二行肩负着让第一行全部为0的使命。
      3 // 不能随便动、必须和第一行完全对应。依次类推。知道最后一行都是确定的。然后、
      4 // 如果最后一行的操作同时使最后一行全部变成0了。就是可行方案。否则不是。
      5 // QAQ。然而纠结了半天新的问题是怎么代码实现呢。恩。第一行的操作遍历可以抽象成一个10进制数0到(2^n-1)的变换、
      6 // 然后每次都按行搜索下去。好了。具体的看代码吧。。QAQ、
      7 
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <iostream>
     11 #define maxn 10000010
     12 #include <algorithm>
     13 using namespace std;
     14 
     15 int m, n;
     16 int mp[20][20];
     17 int num[20][20];
     18 int ans;
     19 int mpcpy[20][20];
     20 int cnt;
     21 
     22 int dir[5][2] = {1, 0, -1, 0, 0, 1, 0, -1, 0, 0};
     23 int ansnum[20][20];
     24 string ans2[1000];
     25 
     26 int pow(int n) {
     27     int temp = 1;
     28     for (int i=0; i<n; ++i) {
     29         temp *= 2;
     30     }
     31     return temp;
     32 }
     33 
     34 bool check(int x, int y) {
     35     if (x >=0 && x < m && y >= 0 && y < n)
     36         return true;
     37     return false;
     38 }
     39 
     40 void filp(int ii, int jj) {
     41     for (int i=0; i<5; ++i) {
     42         int x = ii + dir[i][0];
     43         int y = jj + dir[i][1];
     44         if (check(x, y))
     45          mpcpy[x][y] = 1 - mpcpy[x][y];
     46     }
     47 }
     48 
     49 int min(int a, int b) {
     50     if (a < b) return a;
     51     else return b;
     52 }
     53 
     54 int dfs() {
     55     int tempans = 0;
     56     for (int i=0; i<m; ++i) {
     57         for (int j=0; j<n; ++j) {
     58             mpcpy[i][j] = mp[i][j];
     59         }
     60     }
     61 
     62     for (int i=0; i<n; ++i) {
     63         if (num[0][i] == 1) {
     64             tempans++;
     65             filp(0, i);
     66         }
     67     }
     68 
     69     for (int i=0; i<m-1; ++i) {
     70         for (int j=0; j<n; ++j) {
     71             if (mpcpy[i][j] == 1) {
     72                 tempans++;
     73                 num[i+1][j] = 1;
     74                 filp(i+1, j);
     75             }
     76         }
     77     }
     78 
     79     for (int i=0; i<m; ++i) {
     80         for (int j=0; j<n; ++j)
     81         if (mpcpy[i][j] == 1)
     82             return maxn;
     83     }
     84     return tempans;
     85 }
     86 
     87 int main() {
     88     while(cin >> m >> n) {
     89         for (int i=0; i<m; ++i) {
     90             for (int j=0; j<n; ++j) {
     91                 cin >> mp[i][j];
     92             }
     93         }
     94         int temp = 0;
     95         int tempmax = pow(n+1) - 1;
     96         ans = maxn;
     97         cnt = 0;
     98         while(temp < tempmax) {
     99             memset(num, 0, sizeof(num));
    100             string anstemp = "";
    101             int temp2 = temp;
    102             for (int i=0; i<n; ++i) {
    103                 num[0][i] = temp2 % 2;
    104                 temp2 /= 2;
    105             }
    106             temp++;
    107 
    108             if (ans > dfs()) {
    109                 ans = dfs();
    110                 for (int i=0; i<m; ++i) {
    111                     for (int j=0; j<n; ++j) {
    112                         anstemp += '0' + num[i][j];
    113                     }
    114                 }
    115                 ans2[cnt++] = anstemp;
    116             }
    117         }
    118 
    119         if (ans == maxn) {
    120             cout << "IMPOSSIBLE
    ";
    121             continue;
    122         }
    123         sort(ans2, ans2+cnt);
    124         int tt = 0;
    125         for (int i=0; i<m; ++i) {
    126             for (int j=0; j<n; ++j) {
    127                 if (j == 0) cout << ans2[0][tt++];
    128                 else cout << ' ' << ans2[0][tt++];
    129             }
    130             cout << endl;
    131         }
    132     }
    133     return 0;
    134 }
    View Code

    我想说这个题在毫无思路的情况下,被小王sir告知思路,然后,尝试代码实现写出来的。感觉自己好厉害【傲娇脸】。第一行的枚举用十进制数的二进制形式表示。记录最终答案的过程。啊哈。以上。

  • 相关阅读:
    SSH整合简述一
    错误:找不到类org.springframework.web.context.ContextLoaderListener
    Spring(七)持久层
    CSS 类选择器(四)
    BeanFactory not initialized or already closed
    Spring(六)AOP切入方式
    Postman Mock Server
    Sentry快速开始并集成钉钉群机器人
    OAuth2实现单点登录SSO
    图解TCP三次握手
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5139019.html
Copyright © 2011-2022 走看看