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