zoukankan      html  css  js  c++  java
  • poj3279搜索详解

    这道搜索题和大部分的题都不太一样,没有一个明显的思路,格子间的状态都是互相影响的,只能通过枚举第一行,逐行往下搜。

    详解:

    1、如何搜索:如果从上到下搜索,当前行是否需要反转取决于上一行的状态,通过翻转当前行使上一行为0,而不是通过上一行翻转为0后,看当前行的状态判断自己是否需要翻转,否则还会继续影响上一行。所以枚举一下第一行所有的状态,搜索到最后一行结束,如果可以保证最后一行都是0,那么方案可以,否则重新定义第一行的状态,继续搜索,找出使反转次数最少的方案。

    2、保证字典序最小:按照字典序从小到大搜索(如何实现看下文)

    Tips:

    如何枚举:如果一行有N个格子,每个格子有两种状态,那么一共有2^n种,例如n = 6;001100则指第2、3位(i从0开始)翻转。字典序从小到大就是i从0到1<<n遍历(从一行的最后一位开始考虑翻转)

    获取第一行定义的状态 i>>j &1:i>>j为 i 状态下 第j位状态,为什么&1?因为题里定义0是不需要反转的,在get函数中判断某行某一位是否翻转也要注意一下,get函数中枚举上下左右及本身的5个格子,累加这几个格子的翻转值,假如这5个格子中有s个翻转过,那么此时这个格子就相当于原来的格子翻转了s次,加上原来的状态,和1相与便是这个格子的是否需要翻转的值。大家可以想一下如果初始问题设置为(0需要翻转,1不需要)时,就是和0相与了。

    有点绕,当前行是否需要反转取决于上一行的是否为黑色!!

     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <string>
     4 #include <algorithm>
     5 #include <string>
     6 #include <string.h>
     7 #include <math.h>
     8 #include <queue>
     9 #define MAXN 16
    10 #define INF 1<<30
    11 using namespace std;
    12 
    13 int a[MAXN][MAXN],flip[MAXN][MAXN],ans[MAXN][MAXN];
    14 int m,n;
    15 int dx[5] = {0,1,0,-1,0};
    16 int dy[5] = {-1,0,0,0,1};
    17 int get(int x,int y)
    18 {
    19     int cnt = a[x][y];//当前为t的格子,翻过n次后,状态与(t+n)%2等价
    20     for(int i = 0;i<5;i++)
    21     {
    22         int a = x + dx[i];
    23         int b = y + dy[i];
    24         if(a>=0&&a<m&&b>=0&&b<n)
    25             cnt += flip[a][b];
    26     }
    27     return cnt&1;
    28 }
    29 int cal()
    30 {
    31     int i,j;
    32     for(i = 1;i<m;i++)
    33     {
    34         for(j = 0;j<n;j++)
    35         {
    36             if(get(i-1,j))
    37                 flip[i][j] = 1;
    38         }
    39     }
    40     for(i = 0;i<n;i++)
    41     {
    42         if(get(m-1,i))//(i-1,j)为黑色,则反转(i,j)
    43             return INF;
    44     }
    45     int cnt = 0;
    46      for(i = 0;i<m;i++)
    47         for(j = 0;j<n;j++)
    48             cnt+=flip[i][j];
    49 
    50     return cnt;
    51 }
    52 int main()
    53 {
    54     freopen("caicai.txt","r",stdin);
    55     while(cin>>m>>n)
    56     {
    57         int i,j;
    58         for(i = 0;i<m;i++)
    59             for(j = 0;j<n;j++)
    60             cin>>a[i][j];
    61         int cnt = INF;
    62         for(i = 0;i < 1<<n ;i++)
    63         {
    64             memset(flip,0,sizeof(flip));
    65             for(j = 0;j<n;j++)
    66             {
    67                 flip[0][j] = i>>j & 1;
    68             }
    69             int temp = cal();
    70             if(temp < cnt)
    71             {
    72                 cnt = temp;
    73                 for(int p  = 0;p<m;p++)
    74                     for(int q = 0;q<n;q++)
    75                         ans[p][q] = flip[p][q];
    76             }
    77 
    78         }
    79         if(cnt == INF)
    80             cout<<"IMPOSSIBLE
    ";
    81         else{
    82             for(i = 0;i<m;i++)
    83             {
    84                 for(j = 0;j<n;j++)
    85                 {
    86                     cout<<ans[i][j];
    87                     if(j!=n-1)
    88                         cout<<' ';
    89                     else
    90                         cout<<'
    ';
    91                 }
    92             }
    93         }
    94 
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    程序员的进阶课-架构师之路(2)-数组
    程序员的进阶课-架构师之路(1)-数据结构与算法简介
    ASP.NET开发实战——(三)第一个ASP.NET应用《MyBlog》
    ASP.NET开发实战——(二)为什么使用ASP.NET
    ASP.NET开发实战——(一)开篇-用VS创建一个ASP.NET Web程序
    asp.net core 系列 12 选项 TOptions
    Linux编程 1 (文件系统路径说明, 目录结构说明)
    asp.net core 系列 9 三种运行环境和IIS发布
    asp.net core 系列 6 MVC框架路由(下)
    asp.net core 系列 4 注入服务的生存期
  • 原文地址:https://www.cnblogs.com/caitian/p/5396946.html
Copyright © 2011-2022 走看看