C小加

厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Ural 1060 Flip Game 解题报告

Posted on 2011-11-25 10:43 C小加 阅读(1750) 评论(0)  编辑 收藏 引用 所属分类: 解题报告
暴力DFS,对每一种棋子只有两种情况,翻或者不翻,而且不论是谁先翻或者谁后翻都不影响最终的结果。只有2^16种可能。剪枝:当步数小于已知的最小步数时不再搜索,当步数大于16时不再搜索。搜过之后别忘了回溯。

#include
<iostream>
#include
<cstdio>
#include
<cstring>
using namespace std;
const int INF=0x7fffffff-1;
char s[4][4];
int a[5][5];
int mina=INF;
bool Achieve()
{
    
int t=a[0][0];
    
for(int i=0;i<4;i++)
        
for(int j=0;j<4;j++)
            
if(a[i][j]!=t) return false;
    
return true;
}
void Flip(int i,int j)
{
    a[i][j]
=!a[i][j];
    
if(i>=1) a[i-1][j]=!a[i-1][j];
    
if(j>=1) a[i][j-1]=!a[i][j-1];
    a[i
+1][j]=!a[i+1][j];
    a[i][j
+1]=!a[i][j+1];
}
void DFS(int n,int pos)
{
    
if(Achieve())
    {
if(pos<mina) mina=pos;return;}
    
if(pos>mina) return;
    
if(n>16return;
    DFS(n
+1,pos);
    
int i=n/4;
    
int j=n%4;
    Flip(i,j);
    DFS(n
+1,pos+1);
    Flip(i,j);
    
return;
}

int main()
{
    memset(a,
0,sizeof(a));
    scanf(
"%s %s %s %s",s[0],s[1],s[2],s[3]);
    
for(int i=0;i<4;i++)
        
for(int j=0;j<4;j++)
            
if(s[i][j]=='b') a[i][j]=0;
            
else a[i][j]=1;
    DFS(
0,0);
    
if(mina<17) printf("%d\n",mina);
    
else printf("Impossible\n");
    
return 0;
}

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理