习题7-6 重叠的正方形(Overlapping Squares, Xia'an 2006, UVa12113)

时隔13天,终于又a了一道水题。

一共9个位置,枚举9的6次种情况。

状态用二进制压缩一下。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define SF(a) scanf("%d", &a)
#define PF(a) printf("%d\n", a)  
#define SFF(a, b) scanf("%d%d", &a, &b)  
#define SFFF(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define FOR(i, a, b) for(int i = a; i < b; ++i)
#define LL long long
#define maxn 10
#define maxm 205
#define mod 1000000007
#define INF 10000
using namespace std;
//-------------------------CHC------------------------------//
struct State {
	int r[5], c[4];
	State() { CLEAR(r, 0), CLEAR(c, 0); }
};

char g[5][15];
State tag;
bool vis[3][3];
const int dx[] = { 0, 1, 2 };
const int dy[] = { 0, 1, 2 };

void init_target() {
	FOR(i, 0, 5) tag.r[i] = 0;
	FOR(i, 0, 4) tag.c[i] = 0;
}

void get_target() {
	FOR(i, 0, 5) FOR(j, 0, 9) {
		int c = j >> 1;
		if (j & 1) {
			if (g[i][j] == '_') tag.r[i] |= (1 << c);
		}
		else {
			if (g[i][j] == '|') tag.c[i - 1] |= (1 << c);
		}
	}
}

bool have_found(State s) {
	bool ok = true;
	FOR(i, 0, 5) if (s.r[i] != tag.r[i]) ok = false;
	FOR(i, 0, 4) if (s.c[i] != tag.c[i]) ok = false;
	return ok;
}

State put(State s, int x, int y) {
	if (s.r[x + 1] & (1 << y)) s.r[x + 1] -= (1 << y);
	if (s.r[x + 1] & (1 << (y + 1))) s.r[x + 1] -= (1 << (y + 1));
	if (s.c[x] & (1 << (y + 1))) s.c[x] -= (1 << (y + 1));
	if (s.c[x + 1] & (1 << (y + 1))) s.c[x + 1] -= (1 << (y + 1));
	s.r[x] |= 1 << y, s.r[x] |= 1 << (y + 1);
	s.r[x + 2] |= 1 << y, s.r[x + 2] |= 1 << (y + 1);
	s.c[x] |= 1 << y, s.c[x + 1] |= 1 << y;
	s.c[x] |= 1 << (y + 2), s.c[x + 1] |= 1 << (y + 2);
	return s;
}

void print_state(State s) {
	char t[5][10];
	FOR(i, 0, 5) FOR(j, 0, 9) t[i][j] = ' ';
	FOR(i, 0, 5) FOR(j, 0, 4) {
		if (s.r[i] & (1 << j)) t[i][j << 1 | 1] = '_';
		else t[i][j << 1 | 1] = ' ';
	}
	FOR(i, 0, 4) FOR(j, 0, 5) {
		if (s.c[i] & (1 << j)) t[i + 1][j << 1] = '|';
		else t[i + 1][j << 1] = ' ';
	}
	FOR(i, 0, 5) {
		FOR(j, 0, 9) putchar(t[i][j]);
		puts("");
	}
}

bool dfs(State s, int d) {
	if (d > 6) return false;
	if (have_found(s)) return true;
	FOR(i, 0, 3) FOR(j, 0, 3) {
		if (!vis[i][j]) {
			vis[i][j] = true;
			State newstate = put(s, i, j);
			//if (d == 0) printf("%d %d\n", i, j), print_state(newstate);
			if (dfs(newstate, d + 1)) return true;
			vis[i][j] = false;
		}
	}
	return false;
}

int main() {
	int kase = 1;
	//IN(); OUT();
	while (fgets(g[0], 15, stdin) && g[0][0] != '0') {
		FOR(i, 1, 5) fgets(g[i], 15, stdin);
		init_target();
		get_target();
		//print_state(tag);
		printf("Case %d: ", kase++);
		State s;
		CLEAR(vis, 0);
		puts(dfs(s, 0) ? "Yes" : "No");
	}
	return 0;
}

你可能感兴趣的:(紫书,第七章,习题)