UVa 12113 重叠的正方形(Overlapping Squares)

题目:
给定一个4*4的棋盘和棋盘上所呈现出来的纸张边缘,问能否用不超过6张纸,搞出这种情况。

要点:
无, 测试数据很水,不用担心超时
在我自己的电脑上运行肯定超过3s了,那些测试样例。。
但是110ms过了

代码有点长,但是非常好理解,都注释了。

#include
#define LL long long
using namespace std;
int pic[5][10];  //定义原始图形 
int p[5][10];   //之后的图形

/*
0表示 " "
1表示 "_"
2表示 "|"

一个正方形的填充区域
01010
20002
21012
*/

bool vis[10];
bool read() {
	memset(pic, 0, sizeof(pic));
	memset(p, 0, sizeof(p));
	memset(vis, 0, sizeof(vis));
	//五行 7列
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 10; j++) {
			char ch;
			ch = cin.get();
			if (ch == '0') return false;
			if (isspace(ch)) {
				pic[i][j] = 0;
			}
			else if (ch == '_') {
				pic[i][j] = 1;
			}
			else if (ch == '|') {
				pic[i][j] = 2;
			}
			else {
				cin.get(); //读掉换行
				break;
			}
		}
	}
	// for(int i = 0; i < 5; i++) {
	//     for(int j = 0; j < 10; j++) {
	//         cout << pic[i][j];
	//     }
	//     cout << endl;
	// }
	return true;
}

//定义偏移量
int offx[] = { 0, 1, 2 };
int offy[] = { 0, 1, 2 };

string s[3] = { "01010", "20002", "21012" };

//放置 0 - 8 个图形
//返回原来的情况
vector<string> put(int num1) {
	int ox = num1 / 3;
	int oy = num1 % 3;
	vector<string> ss;
	ss.resize(5);
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 5; j++) {
			ss[i].push_back(p[i + ox][j + oy * 2]);
			if (i == 0 && s[i][j] == '0') continue;
			p[i + ox][j + oy * 2] = s[i][j] - '0';
		}
	}
	return ss;
}

//回溯用
void reset(int num1, vector<string> ss) {
	int ox = num1 / 3;
	int oy = num1 % 3;
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 5; j++) {
			if (i == 0 && s[i][j] == '0') continue;
			p[i + ox][j + oy * 2] = ss[i][j];
		}
	}
}

bool check() {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 10; j++) {
			if (pic[i][j] != p[i][j]) return false;
		}
	}
	return true;
}

//搜索与回溯

bool dfs(int d, int maxd) {
	//cout << "d: " << d << endl;
	//for(int i = 0; i < 5; i++) {
	//	for(int j = 0; j < 10; j++) {
	//		//cout << p[i][j];
	//		if (p[i][j] == 0) cout << " ";
	//		if (p[i][j] == 1) cout << "_";
	//		if (p[i][j] == 2) cout << "|";
	//	}
	//	cout << endl;
	//}
	//cout << endl;
	if (d == maxd) {
		if (check()) 
			return true;
		return false;
	}
	if (check()) return true;
	for (int i = 0; i < 9; i++) {
		if (vis[i]) continue;
		vis[i] = true;
		vector<string> ss = put(i);
		if (dfs(d + 1, maxd))
			return true;
		reset(i, ss);
		vis[i] = false;
	}
	return false;
}

int main() {
	// freopen("in.txt", "r", stdin);
	// freopen("out.txt", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	int kase = 0;
	while (read()) {
		cout << "Case " << ++kase << ": ";
		if (check() || dfs(0, 6)) {
			cout << "Yes" << endl;
			continue;
		}
		cout << "No" << endl;
	}
	return 0;
}

你可能感兴趣的:(搜索与回溯,UVA)