标签:
http://poj.org/problem?id=1753
拿到这道题第一想法就是深搜。
简单介绍一下题意:
一个4*4棋盘, 输入为初始状态。flip一颗棋子, 本身和周围的四颗棋子会跟着翻动, 问最短需要翻动几颗棋子可以使棋盘全部黑或者白?
首先看一下从题中得到的信息:
1. 这个棋盘很小, 4*4
2. 翻动一个棋子两次相当于没翻, 于是步数最大只能为16
于是想到可以将深度作为函数的参数, 将从0依次递增的步数作为终止条件, 即当深度等于步数长度的时候就判断当前棋盘状态是否OK,如果不OK就继续回溯, 直至走完当前规定步数的所有情况。
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; int map[5][5]; int step; int flag; const int dx[5] = { 0, 0, 0, 1, -1 }; const int dy[5] = { 0, 1, -1, 0, 0 }; bool is_ok() { int sum = 0; for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 4; j++ ) { sum += map[i][j]; } } if( sum == 0 || sum == 16 ) return true; else return false; } bool is_valid( int x, int y ) { if( 0 <= x && x <= 3 && 0 <= y && y <= 3 ) return true; else return false; } void flip( int x, int y ) { for( int i = 0; i <= 4; i++ ) { int x2 = x + dx[i]; int y2 = y + dy[i]; if( is_valid( x2, y2 ) ) { map[x2][y2] = !map[x2][y2]; } } } void dfs( int x, int y, int deep ) { if( deep == step ) { flag = is_ok(); return; } if( flag || x == 4 ) return; flip( x, y ); if( y < 3 ) dfs( x, y+1, deep+1 ); else dfs( x+1, 0, deep+1 ); flip( x, y ); if( y < 3 ) dfs( x, y+1, deep ); else dfs( x+1, 0, deep ); return; } int main() { char ch; for( int i = 0; i < 4; i++ ) { for( int j = 0; j < 4; j++ ) { cin >> ch; if( ch == ‘b‘ ) map[i][j] = 0; else map[i][j] = 1; } } for( step = 0; step <= 16; step++ ) { flag = false; dfs( 0, 0, 0 ); if( flag ) break; } if( flag ) { cout << step << endl; } else { cout << "Impossible" << endl; } return 0; }
这本来是道很简单的dfs题, 我却做了挺久, 究其原因, 还是太水。 引用邝神一句话:“人十我百, 人百我万!”
标签:
原文地址:http://www.cnblogs.com/FriskyPuppy/p/5929149.html