UVa 519 - Puzzle (II)

題目:有一些矩形的拼圖小塊,拼成一個規定的矩形,小塊上可能有凸起或凹陷。

分析:圖論、搜索。直接利用回溯法求解,找到一組解直接返回。

            可以利用凹凸數量相同,邊界個數等於邊上塊的個數。

說明:還差四題850╮(╯▽╰)╭。

#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

char block[36][5];
int  size[36];
int  save[7][7];

int dfs(int n, int m, int now, int sum)
{
	if (now >= sum) {
		return 1;
	}
	int r = now/m, c = now%m;
	for (int i = 0; i < sum; ++ i) {
		if (!size[i]) continue;
		if (r == 0   && block[i][0] != 'F') continue;
		if (c == m-1 && block[i][1] != 'F') continue;
		if (r == n-1 && block[i][2] != 'F') continue;
		if (c == 0   && block[i][3] != 'F') continue;
		if (c != m-1 && block[i][1] == 'F') continue;
		if (r != n-1 && block[i][2] == 'F') continue;
		if (r && block[save[r-1][c]][2]+block[i][0] != 'O'+'I') continue;
		if (c && block[save[r][c-1]][1]+block[i][3] != 'O'+'I') continue;
		size[i] --;
		save[r][c] = i;
		if (dfs(n, m, now+1, sum)) {
			return 1;
		}
		size[i] ++;
	}
	return 0;
}

int main()
{
	int  n, m;
	char buf[5];
	while (~scanf("%d%d",&n,&m) && m && n) {
		int IO_count = 0, FF_count = 0, B_count = 0;
		for (int i = 0; i < n*m; ++ i) {
			scanf("%s",block[B_count]);
			for (int j = 0; j < 4; ++ j) {
				if (block[B_count][j] == 'I') {
					IO_count ++;
				}else if (block[B_count][j] == 'O') {
					IO_count --;
				}else {
					FF_count ++;
				}
			}
			int same = 0;
			for (int j = 0; j < B_count; ++ j) {
				if (!strcmp(block[j], block[B_count])) {
					size[j] ++;
					same = 1;
					break;
				}
			}
			if (!same) {
				size[B_count ++] = 1;
			}
		}
		
		if (IO_count == 0 && FF_count == m+m+n+n && dfs(n, m, 0, n*m)) {
			puts("YES");
		}else {
			puts("NO");
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值