UVA 10651 Pebble Solitaire(bfs+hash)

题目大意:
给出一个12格的棋盘,'o'代表摆放棋子,'-'代表没有棋子,当满足'-oo'时, 最右边的棋子可以跳到最左边的位子,而中间的棋子则被消除,'o--', 问对于一个给定了的棋盘,通过上述消除棋子的方法最后最少剩几个棋子在棋盘上。

解析:

这题可以直接暴力解决,方法是bfs+hash判重,对于每种当前的状态,可以衍生出新的状态,把这些状态都push进队列中,用一个变量记录这些状态中点最少的。

#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
int vis[1 << 13];
const int INF = 0x3f3f3f3f;
struct Node {
	string st;
	int num;
	Node() {}
	Node(string _st,int _num) {
		st = _st;
		num = _num;
	}
};
int hash(string st) {
	int sum = 0;
	for(int i = 0; i < st.size(); i++) {
		if(st[i] == 'o') {
			sum = sum * 2 + 1;
		}else {
			sum = sum * 2;
		}
	}
	return sum;
}
int try_to_insert(string st) {
	int code = hash(st);
	if(vis[code]) {
		return 0;
	}
	vis[code] = true;
	return 1;
}
int bfs(string state) {
	int num;
	string rear;
	queue<Node> que;
	memset(vis,0,sizeof(vis));
	vis[hash(state)] = true;
	num = 0;
	for(int i = 0; i < 12; i++) {
		if(state[i] == 'o') {
			num++; 
		}
	}
	que.push(Node(state, num));
	int ans = INF;
	while(!que.empty()) {
		Node front = que.front();
		ans = min(ans,front.num);
		que.pop();
		for(int i = 0; i < 10; i++) {
			if(front.st[i] == 'o' && front.st[i+1] == 'o' && front.st[i+2] == '-') {
				rear = front.st;
				rear[i] = '-';
				rear[i+1] = '-';
				rear[i+2] = 'o';
				num = front.num - 1;
			}else if(front.st[i] == '-' && front.st[i+1] == 'o' && front.st[i+2] == 'o') {
				rear = front.st;
				rear[i] = 'o';
				rear[i+1] = '-';
				rear[i+2] = '-';
				num = front.num - 1;
			}
			if(try_to_insert(rear)) {
				que.push(Node(rear,num));
			}
		}
	}
	return ans;
}
int main() {
	int T;
	string state;
	cin >> T;
	while(T--) {
		cin >> state;
		int ans = bfs(state);
		cout << ans << endl;
	}
	return 0;
}

你可能感兴趣的:(uva,Pebble,Solitaire,10651)