zoukankan      html  css  js  c++  java
  • 翻牌Flip Game POJ 1753

    http://poj.org/problem?id=1753

    这个题目一看就要用搜索,但是如何最小?  题目只有4*4 行 ,所以好说了,暴力dfs。

     1 #include<stdio.h>
     2 char map[4][4];
     3 int vis[4][4];
     4 int step,flag;
     5 int judge()
     6 {
     7      int i,j;
     8      for(i=0;i<4;i++)
     9        for(j=0;j<4;j++)
    10          if(vis[i][j]!=vis[0][0])
    11          return 0;
    12 
    13          return 1;
    14 }
    15 void turn(int i,int j)
    16 {
    17      vis[i][j]=!vis[i][j];
    18      if(i>0) vis[i-1][j]=!vis[i-1][j];
    19      if(i<3)  vis[i+1][j]=!vis[i+1][j];
    20      if(j>0)  vis[i][j-1]=!vis[i][j-1];
    21      if(j<3)  vis[i][j+1]=!vis[i][j+1];
    22 }
    23 void dfs(int i,int j,int step1)
    24 {
    25 
    26      if(step==step1)
    27      {
    28           if(judge())
    29           flag=1;
    30 
    31           return ;
    32      }
    33      if(flag ||i==4)  return ;
    34      turn(i,j);
    35      if(j<3)
    36      dfs(i,j+1,step1+1);
    37      else
    38      dfs(i+1,0,step1+1);
    39      turn(i,j);
    40           if(j<3)
    41      dfs(i,j+1,step1);
    42      else
    43      dfs(i+1,0,step1);
    44      return ;
    45 }
    46 int main()
    47 {
    48      int i,j;
    49      for(i=0;i<4;i++)
    50      scanf("%s",map[i]);
    51      for(i=0;i<4;i++)
    52      {
    53           for(j=0;j<4;j++)
    54           {
    55                if(map[i][j]=='b')
    56           vis[i][j]=1;
    57           else
    58           vis[i][j]=0;
    59 
    60           }
    61 
    62      }
    63      flag=0;
    64      for(step=0;step<=16;step++)
    65      {
    66           dfs(0,0,0);
    67           if(flag)
    68           break;
    69      }
    70      if(flag)
    71      printf("%d
    ",step);
    72      else
    73      printf("Impossible
    ");
    74      return 0;
    75 }
    View Code

    基于以上代码,我自己又写了一个,本想优化优化,结果一直wa,看了一下午加一晚上,还是没有搞清。

    找啊找,找不同。先把代码放在这里,过几天再看看,说不定就找到原因了,读者能找到不同么?欢迎来踩!

     1 #include<stdio.h>
     2 #include<string.h>
     3 char m[4][10];
     4 int s[4][4];
     5 int limit;
     6 int ok=0;//是否完成反转,为一时,全部一样
     7 int check()
     8 {
     9     for(int i=0;i<4;i++)
    10         for(int k=0;k<4;k++)
    11     {
    12         if(s[i][k]!=s[0][0])return 0;
    13     }
    14     return 1;//全部一样的时候返回1,不一样的时候返回0
    15 }
    16 void turn(int x,int y)
    17 {
    18     s[x][y]=!s[x][y];
    19     if(x>=1)s[x-1][y]=!s[x-1][y];
    20     if(x<=2)s[x+1][y]=!s[x+1][y];
    21     if(y>=1)s[x][y-1]=!s[x][y-1];
    22     if(y<=2)s[x][y+1]=!s[x][y+1];
    23 }
    24 void dfs(int x,int y,int step)
    25 {   
    26     if(step==limit&&check()){ok=1;printf("%d
    ",limit);return;}
    27     if(x<0||y<0||x>=4||y>=4||step>limit||ok)
    28     {
    29         return;
    30     }
    31 
    32     turn(x,y);//假设要翻开
    33     if(y<=2)dfs(x,y+1,step+1);
    34     else dfs(x+1,0,step+1);
    35     turn(x,y);//运行到此步说明以上翻牌不行时,应该翻回去,翻其他的牌
    36     if(y<=2)dfs(x,y+1,step);
    37     else dfs(x+1,0,step);
    38     return ;
    39 }
    40 
    41 int main()
    42 {
    43     for(int i=0;i<4;i++)
    44         scanf("%s",m[i]);
    45     for(int i=0;i<4;i++)
    46         {
    47             //printf("%s
    ",m[i]);
    48             for(int k=0;k<4;k++)
    49             {
    50                 if(m[i][k]=='b')s[i][k]=0;
    51                 else s[i][k]=1;
    52             }
    53         }
    54 
    55     for(limit=0;limit<=16;limit++)
    56     {
    57         dfs(0,0,0);
    58         if(ok==1)break;
    59     }
    60     if(ok==0)printf("Impossible
    ");
    61     else printf("%d
    ",limit);
    62     return 0;
    63 }
    View Code

     无语了,原来我在函数验证时输出了一次,忘记把代码注释掉。

    一段时间后,我又重写了此题,作为复习,发现新的代码更为清晰。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define M 4
    #define mem0(f) memset(f,0m,sizeof(f))
    char s[10][10];
    int map[M][M];
    int ok,limit;
    void check()
    {
        for(int i=0;i<M;i++)
            for(int k=0;k<M;k++)
        {
            if(map[i][k]!=map[0][0])
            {
                ok=0;return;
            }
        }
        ok=1;
    }
    void turn(int x,int y)
    {
        map[x][y]=!map[x][y];
        if(x>0)map[x-1][y]=!map[x-1][y];
        if(x<M-1)map[x+1][y]=!map[x+1][y];
        if(y>0)map[x][y-1]=!map[x][y-1];
        if(y<M-1)map[x][y+1]=!map[x][y+1];
    }
    void dfs(int x,int y,int step)
    {
        check();
        //printf("ok=%d
    ",ok);
        if(x<0||y<0||x>=M||y>=M||ok==1||step==limit)return;
        turn(x,y);
        if(x==M-1)dfs(0,y+1,step+1);
        else dfs(x+1,y,step+1);
        if(ok)return;
        turn(x,y);
        if(x==M-1)dfs(0,y+1,step);
        else dfs(x+1,y,step);
        return;
    }
    int main()
    {
        while(~scanf("%s",s[0]))
        {
            scanf("%s",s[1]);
            scanf("%s",s[2]);
            scanf("%s",s[3]);
            for(int i=0;i<M;i++)
            {
                for(int k=0;k<M;k++)
                {
                    if(s[i][k]=='b')map[i][k]=0;
                    else map[i][k]=1;
                }
            }
            ok=0;
            for(int i=0;i<=16;i++)
            {
                limit=i;
                dfs(0,0,0);
                if(ok){break;}
            }
            if(ok)printf("%d
    ",limit);
            else printf("Impossible
    ");
        }
        return 0;
    }
    View Code

    这应该也是思维提升的表现吧。好了,好好加油,看看日后有没有一个比这个暴力的方法更好的解法,毕竟搜索时这个算法重复了好多次。

  • 相关阅读:
    杭电oj2032、2040、2042、2054、2055
    杭电oj2022-2030
    杭电oj2012-2021
    杭电oj2000-2011
    值得思考的几句话,放在这看看
    CEO 是一家创业公司的天花板
    致敬骄傲的产品人
    【新业务搭建】竞争情报业务规划及体系构建的思考——By Team
    微软威胁情报中心总经理的十句话——From John Lambert——太精辟了.......
    【调研与分析】标杆学习、知识管理和竞争情报的关系——From Team
  • 原文地址:https://www.cnblogs.com/plank-george-zzo/p/3207946.html
Copyright © 2011-2022 走看看