华容道

华容道最优解,请将代码末的棋盘输入,程序会打印每一步走法。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#define Rep(i, x, y) for (int i = x; i <= y; i ++)
#define Dwn(i, x, y) for (int i = x; i >= y; i --)
#define RepE(i, x) for (int i = pos[x]; i; i = g[i].nex)
#define v g[i].y
#define col(x, y) map[x][y]
#define Nexts sv = encode(map); if (find(sv, d + 1)) { ans[d] = s; return 1; }
using namespace std;
typedef long long ll;
typedef double db;
const int n = 5, m = 4;
int px[14], py[14], l, lim = 1;
int mx[4] = { 0, 1, 0, -1 }, my[4] = { 1, 0, -1, 0 };
ll ans[600];
map<ll, int> vis, step;
ll encode(int map[n + 2][m + 2]) {
	int t1 = 3, t2 = 7;
	bool vd[14];
	memset(vd, 0, sizeof(vd)); vd[0] = 1;
	Rep(i, 1, n) {
		Rep(j, 1, m) {
			int c;
			if (!vd[ c = map[i][j] ]) {
				if (c >= 7) px[t2] = i, py[t2] = j, t2 ++;
				else px[c] = i, py[c] = j;
				vd[c] = 1;
			}
		}
	}
	ll s = 0;
	Dwn(i, 10, 1) s = (s * 4 + py[i] - 1) * 5 + px[i] - 1;
	return s;
}
void decode(ll s, int map[n + 2][m + 2]) {
	Rep(i, 1, 10) px[i] = s % 5 + 1, s /= 5, py[i] = s % 4 + 1, s /= 4;
	Rep(i, 0, n + 1) Rep(j, 0, m + 1) map[i][j] = 0;
	Rep(i, 0, 1) Rep(j, 0, 1) map[ px[1] + i ][ py[1] + j ] = 1;
	Rep(i, 0, 1) map[ px[2] ][ py[2] + i ] = 2;
	Rep(k, 3, 6) Rep(i, 0, 1) map[ px[k] + i ][ py[k] ] = k;
	Rep(k, 7, 10) map[ px[k] ][ py[k] ] = k;
}
bool find(ll s, int d) {
	if (d > lim || step[s] && step[s] < d) return 0;
	if (vis[s] == lim) return 0;
	vis[s] = lim; step[s] = d;
	int map[n + 2][m + 2];
	decode(s, map);
	int _x[3], _y[3], t = 0;
	Rep(i, 1, n) Rep(j, 1, m) if (!map[i][j]) _x[++ t] = i, _y[t] = j;
	if (map[5][2] == 1 && map[5][3] == 1) { printf("%d\n", d); ans[l = d] = s; return 1; }
	ll sv;
	Rep(i, 1, 2) {
		int x = _x[i], y = _y[i], c, x1, y1, x2, y2;
		Rep(j, 0, 3) {
			x1 = x + mx[j], y1 = y + my[j];
			c = map[x1][y1];
			x2 = x + mx[j] * 2, y2 = y + my[j] * 2;
			if (c >= 7) {
				map[x][y] = c, map[x1][y1] = 0;
				Nexts;
				map[x1][y1] = c;
			} else if (c > 1 && c == map[x2][y2]) {
				map[x][y] = c, map[x2][y2] = 0;
				Nexts;
				map[x2][y2] = c;
			}
		}
		map[x][y] = 0;
	}
	Rep(j, 0, 3) {
		int c1, c2, r;
		c1 = map[ _x[1] + mx[j] ][ _y[1] + my[j] ];
		if (!c1) continue ;
		c2 = map[ _x[2] + mx[j] ][ _y[2] + my[j] ];
		if (c1 == c2) {
			r = c1 == 1 ? 2 : 1;
			Rep(i, 1, 2) {
				map[ _x[i] ][ _y[i] ] = c1;
				map[ _x[i] + mx[j] * r ][ _y[i] + my[j] * r ] = 0;
			}
			Nexts;
			Rep(i, 1, 2) {
				map[ _x[i] ][ _y[i] ] = 0;
				map[ _x[i] + mx[j] * r ][ _y[i] + my[j] * r ] = c1;
			}
		}
	}
	return 0;
}
int main()
{
	int t1 = 7, map[n + 2][m + 2];
	Rep(i, 0, n + 1) Rep(j, 0, m + 1) map[i][j] = 0;
	char s[8];
	Rep(i, 1, n) {
		gets (s + 1);
		Rep(j, 1, m) {
			if (s[j] == ' ') map[i][j] = 0;
			else map[i][j] = s[j] == '*' ? t1 ++ : s[j] - '0';
		}
	}
	while (!find( encode(map), 1 )) {
		lim ++;
		if (lim > 200) { puts("no solution"); return 0 ; }
	}
	cout << l << endl;
	Rep(t, 1, l) {
		system("pause");
		decode(ans[t], map);
		Rep(i, 1, n) {
			Rep(j, 1, m) {
				if (map[i][j] >= 7) printf("*");
				else if (!map[i][j]) printf(" ");
				else printf("%d", map[i][j]);
			}
			puts("");
		}
	}

	return 0;
}
/*

3114
3114
5226
5**6
*  *

*/


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值