zoukankan      html  css  js  c++  java
  • 状压dp

       翻转游戏

    题目大意:翻转游戏是在一个 的正方形上进行的,在正方形的 个格上每个格子都放着一个双面的物件。每个物件的两个面,一面是白色,另一面是黑色,每个物件要么白色朝上,要么黑色朝上,每次你只能翻一个物件,从而由黑到白的改变这些物件上面的颜色,反之亦然。每一轮被选择翻转的物件遵循以下规则:

    1. 16个物件中任选一
    2. .翻转所选择的物件的同时,所有与它相邻的左方物件、右方物件、上方物件和下方物件(如果有的话),都要跟着翻转。 

      以下为例:

      bwbw

      wwww

      bbwb

      bwwb

    这里b表示该格子放的物件黑色面朝上表示该格子放的物件白色朝上。如果我们选择翻转第三行的第一个物件,那么格子状态将变为:

      bwbw

      bwww

      wwwb

      wwwb

    游戏的目标是翻转到所有的物件白色朝上或黑色朝上。你的任务就是写一个程序来求最少的翻转次数来实现这一目标。

    输入格式

    输入文件包含行,每行个字符,每个字符wb表示游戏开始时格子上物件的状态。

    输出格

    输出文件仅一个整数,即从给定状态到实现这一任务的最少翻转次数。如果给定的状态就已经实现了目标就输出 0,如果不可能实现目标就输出:Impossible 

    样例输入

    bwwb

    bbwb

    bwwb

    bwww

    样例输出

    4

    思路:因为数据范围太小所以直接暴力即可:先确定第一行状态之后第二行也就确定了(因为一个反转时连带着上下左右一起翻转),依次类推

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int inf=0x3f3f3f3f;
     6 char s[6][6];
     7 char tem[6][6];
     8 int ans=inf,sum=0;
     9 void work(char &ch){//!取地址,不然相当与没
    10      if(ch=='w') ch='b';
    11      else if(ch=='b') ch='w';//不能直接写else
    12 }
    13 void pre(int i,int j){
    14      sum++;
    15      work(tem[i][j]);
    16      work(tem[i-1][j]);
    17      work(tem[i+1][j]);
    18      work(tem[i][j-1]);
    19      work(tem[i][j+1]);
    20 }
    21 void cl(int x,char ch){
    22      memcpy(tem,s,sizeof(s));
    23      sum=0;//因为要用两次注意归0
    24      for(int i=1;i<=4;i++){
    25          if(x&1<<(i-1)) pre(1,i);
    26      }
    27      for(int i=2;i<=4;i++){
    28         for(int j=1;j<=4;j++){
    29             if(tem[i-1][j]!=ch){//因为是一行一行推,若上一行不是‘ch’,交换
    30                  pre(i,j);
    31             }
    32         }
    33      }
    34      for(int i=1;i<=4;i++){
    35           if(tem[4][i]!=ch){
    36               return;
    37           }
    38      }//若最后一行不符合return
    39      ans=min(ans,sum);
    40 }
    41 int main(){
    42     for(int i=1;i<=4;i++) scanf("%s",s[i]+1);
    43     for(int i=0;i<15;i++){//枚举第一行状态(翻或不翻)
    44         cl(i,'w');
    45         cl(i,'b');
    46     }
    47     if(ans==inf) printf("Impossible
    ");
    48     else printf("%d
    ",ans);
    49    return 0;
    50 }
    View Code
  • 相关阅读:
    函数参数太多的一种简化方法
    laravel 获取所有表名
    使用 laravel 的 queue 必须知道的一些事
    git "refusing to merge unrelated histories" 解决方法
    使用 xhprof 进行 php 的性能分析
    php 性能优化
    js原生实现轮播图效果(面向对象编程)
    nextSibling 和nextElementSibling
    如何在页面中使用svg图标
    svg动画 animate
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13205072.html
Copyright © 2011-2022 走看看