http://poj.org/problem?id=1753
题目意思很简单,和POJ1222题一样,前面在POJ1222的解题报告中已经将思路写的很清楚,这里不再赘述。这个题是找出最短的翻转步骤。同样也是遍历解空间。不过需要我们完全遍历,并且分为翻成全白和全黑两种这里都要计算。程序如下:
/*
ID: csuchenan
PROG: POJ 1753 Flip Game
LANG: C++
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std ;
int press[6][7] ;
int state[6][7] ;
int comple() ;
void judge(int flag) ;
int nmin ;
int main()
{
char c ;
int i ;
int j ;
memset(press , 0 , sizeof(press)) ;
memset(state , 0 , sizeof(state)) ;
for(i = 1 ; i <= 4 ; i ++)
{
for(j = 1 ; j <= 4 ; j ++)
{
c = getchar() ;
if(c=='b')
{
state[i][j] = 0 ;
}
else if(c=='w')
{
state[i][j] = 1 ;
}
}
getchar() ;
}
nmin = -1 ;
comple() ;
if(nmin >= 0)
printf("%d\n" , nmin) ;
else
printf("Impossible\n") ;
return 0 ;
}
int comple()
{
int c ;
int ncount = 0 ;
while(ncount < 16)
{
judge(0) ;
judge(1) ;
press[1][1] ++ ;
c = 1 ;
if(nmin == 0)//没有比0更小的翻转次数了,有这个判断条件时,16ms ,没有时32ms
break ;
while(press[1][c] > 1 && c <= 5)
{
press[1][c] = 0 ;
c ++ ;
press[1][c] ++ ;
}
ncount ++ ;
}
return 0 ;
}
void judge(int flag)
{
int c ;
int r ;
for(r = 1 ; r < 4 ; r ++)
{
for(c = 1 ; c <= 4 ; c ++)
{
press[r+1][c] = (state[r][c] + press[r-1][c] + press[r][c-1] + press[r][c+1] + press[r][c] + flag) % 2 ;
}
}
for(c = 1 ; c <= 4 ; c ++)
{
if((press[r][c] + press[r-1][c] + press[r][c-1] + press[r][c+1] + state[r][c] + flag)%2 != 0 )
return ;
}
int nsum ;
nsum = 0 ;
for(r = 1 ; r <= 4 ; r ++)
{
for(c = 1 ; c <= 4 ; c ++)
nsum += press[r][c] ;
}
if(nmin == -1 || nmin > nsum)
nmin = nsum ;
}