1753 题是一个基本的枚举算法的题,基本解题思路就是暴力枚举,但是我们需要知道即便是暴力枚举,也是需要认真分析问题的。
题意:有一个4*4的棋盘,棋盘上有黑白格,每一次你可以翻其中的一个格子。一个格子(x,y)如果被翻,它相邻的前后左右四个格子(如果在棋盘上)也要翻转。现在给你一个初始的棋盘状态,问把这个棋盘翻转到全黑或全白的最少次数;若不能达到全黑或全白,输出Impossible。
思路:只有4*4的棋盘,同时格子只有黑白两面。对于同一个格子,翻两次和不翻没有区别。同时,我们会发现,假如第一行的状态已经确定,那么剩下的行的翻法其实也是确定了的。这样我们从原来需要枚举65536种,到现在只需要枚举第一行16种即可,所以,我们只需要按照求4个数的子集的方式,枚举第一行的翻法即可枚举所有可能形式。
所以,我们需要一个子集递归方法,一个步数求解方法,还有小方法例如判断当前是否全黑或全白、将当前棋子性质翻转等,即可实现枚举。
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
//成功
//暴力枚举,通过枚举第一行元素的组合方式进行暴力搜索
string s[4];//输入矩阵
string tmp[4];//当前棋子状态矩阵
bool b[4];//判断枚举,1-4的子集生成
int foot=100;//步子数
void back2(int x,int y){
//将tmp中的元素性质翻转,例如b转成w,w转成b
if(tmp[x][y]=='b')tmp[x][y]='w';
else
tmp[x][y]='b';
}
bool test(){
//判断输入矩阵是否直接为全黑或者全白
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(s[i