题意:给定一个4*4的棋盘,用不超过6个2*2的纸片堆放出给出的图案,问是否可行
分析:题目很简单,不难想到枚举纸片位置,每张纸片有9中放置方法,只有6张纸片,可以断定不会超时。
题目难点在于数据处理,又是数据结构知识,如何表示数据。
开始我想把格子抽象到数组中,相同的格子用相同的数字表示,一共是4*4。然后直接搜索就完事了。
数据转换部分:
/*cout << " #"<< endl;
cout << " _ _ _ #" << endl;
cout << "| |_ _|#" << endl;
cout << "|_| |#" << endl;
cout << " |_ _|#" << endl;*/
string s[5]; int kase = 1;
while (getline(cin,s[0])&&s[0][0]!='0') {
memset(vis, 0, sizeof(vis));
maxlen = 0;
memset(target, 0, sizeof(target));
for (int i = 1; i < 5; i++)getline(cin,s[i]);
int ans = 1; int first1 = 0;
for (int i = 1;i<5; i++) {
int cnt = 0;
int x1;
int x2; int anr = 0;
for (int j = 0; j < s[i].length()-1; j++) {
if (s[i][j] == '|') {
x1 = j; anr = 1;
for (int z = j + 1; z < s[i].length()-1; z++) {
if (s[i][z] == '|') {
x2 = z;
j = z - 1;
int ok = 0;
for (int w = x1 + 1; w < x2; w += 2) {
if (i == first1+1) { if (!ok) { cnt = x1 / 2; ok = 1; }target[i - 1][cnt++] = ans; continue; }
if (s[i - 1][w] == ' ') {
if (!ok)cnt = x1 / 2;
ok = 1;
target[i - 1][cnt] = target[i - 2][cnt];
cnt++;
}
}
if (!ok) {
for (int z = x1 + 1; z < x2; z += 2) {
if (!ok) { cnt = x1 / 2; ok = 1; }
target[i - 1][cnt++] = ans;
}
}
ans++;
break;
}
}
}
}
if (anr == 0)first1 = i;
}
}
然而数据实际上可以不用这样处理,直接处理,每次放纸片,就在纸片的周围加上“_”和“|”。再判断是否和目标图案相同。
不用特意去找正方形,而是将它们当成一个整体,一幅图案。
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
const int maxn = 1000000 + 5;
using namespace std;
string s[10];
int ans[10][10];
int maps[10][10];
void putmap(int op) {
int row = op / 3;
int col = 2 * (op % 3);
maps[row][col + 1] = maps[row][col + 3] = 2;
maps[row + 2][col + 1] = maps[row + 2][col + 3] = 2;
maps[row + 1][col] = maps[row + 1][col + 4] = 1;
maps[row + 2][col] = maps[row + 2][col + 4] = 1;
maps[row + 2][col + 2] = 0;
maps[row + 1][col + 1] = maps[row + 1][col + 2] = maps[row + 1][col + 3] = 0;
}
bool judge() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 9; j++) {
if (ans[i][j] != maps[i][j])
return false;
}
}
return true;
}
bool dfs(int step) {
if (step > 6) return false;
for (int i = 0; i < 9; i++) {
int remaps[5][10];
for (int k = 0; k < 5; k++)
for (int j = 0; j < 9; j++) {
remaps[k][j] = maps[k][j];
}
putmap(i);
if (judge()) return true;
if (dfs(step + 1)) return true;
for (int k = 0; k < 5; k++)
for (int j = 0; j < 9; j++) {
maps[k][j] = remaps[k][j];
}
}
return false;
}
int main() {
int kases = 1;
while (getline(cin,s[0])) {
memset(ans, 0, sizeof(ans));
memset(maps, 0, sizeof(maps));
if (s[0][0] == '0') break;
for (int i = 1; i < 5; i++)
getline(cin,s[i]);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 9; j++) {
if (s[i][j] == '|')
ans[i][j] = 1;
else if (s[i][j] == '_')
ans[i][j] = 2;
}
}
printf("Case %d: ", kases++);
if (dfs(1)) printf("Yes\n");
else printf("No\n");
}
}