Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 35785 | Accepted: 15628 |
Description
Input
Output
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
Source
分析过程:
本题目的题意为:给你一个4*4的面板,面板上由黑色和白色两种颜色组成,当你翻转其中一个点时,这个点本身连同其周围的紧邻的各个点也随着一起翻转,问你当面板翻转成一种颜色(黑色或者白色)时,最少翻转多少次?
算法可以采用:DFS搜索和回溯,从第一个点开始搜索,(按列搜索或者按行搜索都可以,本方法采用按列搜索),当从(0,0)搜索到(3,3)最右下角元素时,再搜索就超过了面板的范围,此时用(0,4)作为回溯的起点,开始翻转并判断是否所有面板颜色一致?若一致就保存此次所用的翻转次数,如果没有达到一样的颜色,那就回溯到开始的下一个点,比如(2,3),另外需要把你刚才翻转的(3,3)再进行翻转复原操作;当遍历整个点之后,就保存了最少翻转的次数,输出就可以了。
主要的算法核心为:
/***********************************************************************
Copyright (c) 2015,wangzp
All rights no reserved.
Name: 《Flip Game》In PEKING UNIVERSITY ACM
ID: PROBLEM 1753
问题简述: 给出一个正方形4*4矩阵,每个点不是白色就是黑色
当你翻动一个点时,点的周围的点也要跟着翻动;
白色变黑色,黑色变白色,问最少需要用多少步使得板子颜色一致
算法描述:枚举+DFS+回溯。
Date: Oct 14, 2015
***********************************************************************/
#include
const int inf = 9999999;
char s[10];
int map[10][10],i,j;
int ans = inf;
/*判断是否全白色或者黑色*/
int panduan(void)
{
int x = map[0][0];
for (i = 0;i < 4;i++)
{
for (j = 0;j < 4;j++)
{
if (map[i][j] != x)
{
return 0;
}
}
}
return 1;
}
/*翻转算法,对于一个点有四种情况*/
void fan(int x,int y)
{
map[x][y] = !map[x][y];
if(x - 1 >= 0)
{
map[x-1][y] = !map[x-1][y];
}
if(x + 1 < 4)
{
map[x+1][y] = !map[x+1][y];
}
if(y - 1 >= 0)
{
map[x][y-1] = !map[x][y-1];
}
if(y + 1 < 4)
{
map[x][y+1] = !map[x][y+1];
}
}
/*深度搜索算法的实现*/
int dfs(int x,int y,int t)
{
/*如果颜色都一致*/
if (panduan())
{
/*把最小的次数t赋值给ans*/
if (ans > t)
{
ans = t;
}
return 0;
}
/*如果超出范围则返回,递归退出条件*/
if (x >= 4 || y >= 4)
{
return 0;
}
int nx,ny;
nx = (x + 1) % 4;
ny = y + (x + 1) / 4;
/*按列递归入栈,当为最右下角的元素dfs(3,3,0)后,再执行就为dfs(0,4,0),然后return*/
dfs(nx,ny,t);
fan(x,y);
/*当fan(3,3)后假如全部为w,t为翻转次数加1,进入到dsf(0,4,1)后判断return 1*/
dfs(nx,ny,t+1);
/*再把(3,3)复原回去,为了再次重新用新的栈顶元素重新操作,看有没有比记录的次数小*/
fan(x,y);
return 0;
}
int main(void)
{
for (i = 0;i < 4;i++)
{
scanf ("%s",s);
/*初始化面板,0表示黑色,1表示白色*/
for (j = 0;j < 4;j++)
{
if (s[j] == 'b')
{
map[i][j] = 0;
}
else
{
map[i][j] = 1;
}
}
}
dfs(0,0,0);
if (ans == inf )
{
printf ("Impossible\n");
}
else
{
printf ("%d\n",ans);
}
return 0;
}