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告知思路,然后,尝试代码实现写出来的。感觉自己好厉害【傲娇脸】。第一行的枚举用十进制数的二进制形式表示。记录最终答案的过程。啊哈。以上。

  • 相关阅读:
    SharePoint Framework (SPFx) 开发入门教程
    SharePoint 2013 Designer 入门教程
    SharePoint 2013 开发教程
    SharePoint 2013 入门教程
    SharePoint Online 部署SPFx Web部件
    SharePoint Online SPFx Web部件绑定数据
    SharePoint Online 创建SPFx客户端Web部件
    SharePoint Online 配置框架(SPFx)开发环境
    SharePoint Online 创建应用程序目录
    SharePoint Online 启用 IRM
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5139019.html
Copyright © 2011-2022 走看看