title: 习题7-6 UVa12113_重叠的正方形
date: 2021-01-31 19:08:00
categories:
tags:
题目要求用6个长为2的正方形描绘输入的正方形边缘,如果可以描绘,输出yes,否则no
我用一个三维数组描述图形,比如G[i][j][k]表示以i,j点上k方向有边,k取值为0或者1,分别表示右和下
dfs函数设计为寻找遍历路径上没有被遍历过的点作为左上角描绘一个正方形,如果深度大于6返回false
如果通过judge则返回true,如果叶子返回true,也返回true,具体页末看代码,代码结构清晰
[UVA-12113][https://vjudge.net/problem/UVA-12113]
//
// Created by hsby on 2021/1/31.
//
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 5;
enum {RIGHT = 0, DOWN = 1};
int G[maxn][maxn][2];
int GT[maxn][maxn][2];
int vis[maxn-1][maxn-1];
bool judge(){
for (int i = 0; i < maxn; ++i) {
for (int j = 0; j < maxn; ++j) {
for (int k = 0; k < 2; ++k) {
if (G[i][j][k] && !GT[i][j][k]){
return false;
}
}
}
}
return true;
}
void draw(int x, int y){
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
// 描绘水平方向的边
if (i != 1 && j < 2) GT[x+i][y+j][RIGHT] += 1;
// 描绘竖直方向的边
if (j != 1 && i < 2) GT[x+i][y+j][DOWN] += 1;
}
}
}
void erase(int x, int y){
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (i != 1 && j < 2) GT[x+i][y+j][RIGHT] -= 1;
if (j != 1 && i < 2) GT[x+i][y+j][DOWN] -= 1;
}
}
}
bool dfs(int x, int y, int d){
if (judge()) return true;
if (d > 6) {
return false;
}
for (int i = 0; i < maxn-2; ++i) {
for (int j = 0; j < maxn-2; ++j) {
if (vis[i][j]) continue;
vis[i][j] = 1;
draw(i, j);
if (dfs(i, j, d+1)) return true;
erase(i, j);
vis[i][j] = 0;
}
}
return false;
}
int main(){
int T = 1;
string line;
while (cin.peek() != '0'){
memset(G, 0, sizeof(G));
memset(GT, 0, sizeof(GT));
memset(vis, 0, sizeof(vis));
for (int i = 0; i < maxn; ++i) {
getline(cin, line);
for (int j = 0; line[j] != '#'; ++j) {
int tj = j/2;
if (line[j] == '|'){
G[i-1][tj][DOWN] = 1;
}
if (line[j] == '_'){
G[i][tj][RIGHT] = 1;
}
}
}
printf("CASE %d: ", T++);
if (dfs(0, 0, 1)) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章