UVA 10651 Pebble Solitaire

大意不再赘述。

思路:我想用dfs爆过去,扫描一遍,如果两个相邻并且有空位置的话,对于A、B、C来说,假设A为空,B、C满,注意边界条件,那么当前操作只有两种选择,要么选B,要么选C,搜索树是一棵二叉树,然后加上回溯,剪枝等限制条件在极限条件下过不了,但是广搜可以过,不需要判重,只是找到最小的剩余棋子的个数即可。判 DP的方法还再思考。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

struct node
{
	int st[21];
	int step;
}cur, next;

int s[21];

int tot;

int bfs()
{
	queue<node> Q;
	int ans = tot;
	Q.push(cur);
	while(!Q.empty())
	{
		cur = Q.front(); Q.pop();
		for(int i = 0; i < 12; i++) if(cur.st[i])
		{
			next = cur;
			if(i >= 2 && next.st[i-1] && !next.st[i-2])
			{
				next.st[i] = 0, next.st[i-2] = 1, next.st[i-1] = 0;
				next.step--;
				if(ans > next.step) ans = next.step;
				if(ans == 1) break;
				Q.push(next);
			}
			else if(i <= 9 && next.st[i+1] && !next.st[i+2])
			{
				next.st[i] = 0, next.st[i+1] = 0, next.st[i+2] = 1;
				next.step--;
				if(ans > next.step) ans = next.step;
				if(ans == 1) break;
				Q.push(next);
			}
		}
	}
	return ans;
}

void read_case()
{
	char str[26];
	scanf("%s", str);
	tot = 0;
	for(int i = 0; str[i]; i++)
	{
		if(str[i] == '-') s[i] = 0;
		else
		{
			s[i] = 1;
			tot++;
		}
	}
	memcpy(cur.st, s, sizeof(s));
	cur.step = tot;
}

void solve()
{
	read_case();
	int ans = bfs();
	printf("%d\n", ans);
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		solve();
	}
	return 0;
}


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