zoukankan      html  css  js  c++  java
  • Fliptile POJ3279 DFS

    题目链接:Fliptile

    题目大意

    有一个01矩阵,每一次翻转(0->1或者1->0)一个元素,就会把与他相邻的四个元素也一起翻转。求翻转哪些元素能用最少的步骤,把矩阵变成0矩阵。

    思路

    假设确定了第一行的状态,那么第二行需要翻转的所有元素都能确定(上一行如果是1就必须翻转)。因此对于所有第一排的情况,往下递推需要翻转的元素,最后判断最后一行如果全为0则满足条件,记录步骤最少的情况。

    题解

      1 #include <iostream>
      2 #include <cstring>
      3 
      4 using namespace std;
      5 
      6 int n, m, mmin=0x3f3f3f3f;
      7 int map[20][20],tmp[20][20],ans[20][20];
      8 
      9 bool judge(){
     10     for(int i = 0 ; i < m; i++)
     11     {
     12         int time = tmp[n-2][i] + tmp[n-1][i];
     13         if(i != 0)
     14         {
     15             time += tmp[n-1][i-1];
     16         }
     17         if(i != m-1)
     18         {
     19             time += tmp[n-1][i+1];
     20         }
     21         time %= 2;
     22         if(map[n-1][i] ^ time){
     23             return false;
     24         }
     25     }
     26     return true;
     27 }
     28 
     29 void dfs(int k, int num)
     30 {
     31     if(num > mmin) return;
     32     if(k > n-1)    //最后一行遍历    结束,判断最后一行是否全0
     33     {
     34         if(judge() && num < mmin)
     35         {
     36             memcpy(ans, tmp, sizeof(tmp));
     37             mmin = num;
     38         }
     39         return;
     40     }
     41     int flag = 0;
     42     
     43     for(int i = 0; i < m; i++)
     44     {
     45         int time = 0;
     46         time = tmp[k-1][i] + tmp[k-2][i];
     47         if(i != 0)
     48         {
     49             time += tmp[k-1][i-1];
     50         }
     51         if(i != m-1)
     52         {
     53             time += tmp[k-1][i+1];
     54         }
     55         if((map[k-1][i]+time)&1)
     56         {
     57             tmp[k][i] = 1;
     58             flag++;
     59         }
     60         else
     61         {
     62             tmp[k][i] = 0;
     63         }
     64     }
     65     dfs(k+1, num+flag);        //搜索下一行
     66 }
     67 
     68 void todfs(int k, int num)
     69 {
     70     if(k > m - 1){    //遍历完第一行
     71         dfs(1, num);    //从第二行开始
     72         return;
     73     }
     74     tmp[0][k] = 0;
     75     todfs(k+1, num);
     76     tmp[0][k] = 1;
     77     todfs(k+1, num+1);
     78 }
     79 
     80 int main(int argc, char const *argv[])
     81 {
     82 #ifdef debug
     83     freopen("test.txt","r",stdin);
     84 #endif
     85     cin >> n >> m;
     86     for(int i = 0; i < n; i++)
     87     {
     88         for (int j = 0; j < m; j++)
     89         {
     90             cin >> map[i][j];
     91         }
     92     }
     93     todfs(0, 0);
     94     if(mmin == 0x3f3f3f3f)
     95     {
     96         cout << "IMPOSSIBLE" << endl;
     97     }
     98     else
     99     {
    100         for(int i = 0; i < n; i++)
    101         {
    102             for(int j = 0; j < m; j++)
    103             {
    104                 cout << ans[i][j] << " ";
    105             }
    106             cout << endl;
    107         }
    108     }
    109     return 0;
    110 }

    其实这个题用的数组下标最好是从1开始,这样不用把列号是0的元素拿出来单独计算了。

  • 相关阅读:
    ScrollView反弹效果的实现
    Unity 3D本地公布WebPlayer版时&quot;Failed to download data file&quot;解决方式
    win7休眠的开启与关闭方法命令行操作和图文结合的鼠标操作
    使用Javascript D3创建属于你的涂鸦作品
    android获取自己定义控件位置坐标,屏幕尺寸,标题栏,状态栏高度
    [Python]Use Flask-Admin with PostgreSQL
    [LeetCode] Best Time to Buy and Sell Stock
    spring实战五之Bean的自动检测
    FireBug使用总结
    javascript的window.onload()方法和jQuery的$(document).ready()的对比
  • 原文地址:https://www.cnblogs.com/SaltyFishQF/p/10296750.html
Copyright © 2011-2022 走看看