[POJ] 1753.Flip Game

Flip Game

Time Limit: 1000MS      Memory Limit: 65536K
Total Submissions: 51906        Accepted: 21886

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 
it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their 
according to the following rules:

Choose any one of the 16 pieces.
Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the 
bottom of the chosen piece (if there are any).

Consider the following position as an example:

bwbw
wwww
bbwb
bwwb

Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. 
If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the 
field will become:

bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are 
to write a program that will search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve 
the goal of the game from the given position. If the goal is initially achieved, then write 0. If 
it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

题意:4×4的黑白棋盘,规定翻转一个棋子的同时也要翻转它的上、下、左、右的棋子,问给定一个棋盘的棋子状态,至少需要翻转多少次棋子,能使得所有棋子都是同色朝上。
思路:一开始只想到暴力搜索,但具体怎么写还是不会,查阅到一篇博主的文章,原博主题解链接 才有了想法,几乎是照搬的题解了。我好菜。。
总结思路:
1、棋子翻转奇数次才有意义。
2、状态总数仅有2^16,所以可以暴力搜索。
3、用一个int的16位来保存16个棋子的状态。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
int chess = 0;
int state[16];
//得到state数据
void init() {
  for (int i = 1; i <= 16; i++) {
    int v = 0, k = 1 << (i - 1);
    v |= k;
    if ((i + 1) % 4 != 1) v |= k << 1;
    if ((i - 1) % 4 != 0) v |= k >> 1;
    if (i > 4) v |= k >> 4;
    if (i < 13) v |= k << 4;
    state[i - 1] = v;
  }
}
//翻转第i个棋子
void flip(int i) { chess ^= state[i]; }
//判断是否完成
bool check() { return chess == 0 || chess == 0xffff; }
//寻找解 总共还要翻n个,当前翻第i个
bool find(int n, int i) {
  if (n == 0) return check();

  for (; i < 16; i++) {
    flip(i);
    if (find(n - 1, i + 1)) return true;
    flip(i);  //遍历一种后翻转回来以便下次遍历
  }
  return false;
}
int main() {
  init();
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      chess <<= 1;
      if (getchar() == 'b') chess |= 1;
    }
    getchar();
  }

  for (int i = 0; i < 16; i++) {
    if (find(i, 0)) {
      cout << i;
      system("pause");
      return 0;
    }
  }
  cout << "Impossible";
  system("pause");
  return 0;
}

猜你喜欢

转载自blog.csdn.net/ruohua3kou/article/details/82533627