习题7-6:重叠的正方形
题目大意:问能不能用不超过6张2x2的方纸在4x4的方格中摆出给定的图形?
题目分析:暴力枚举出P(9,6)种(最坏情况)方案即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<list>
#include<deque>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const double eps = 1e-6;
const int INF = 1 << 30;
const int dir[4][2] = {1,0,0,1,0,-1,-1,0};
int T, n, m;
bool v[10];
char Map[10][20], p[10][20];
void init()
{
for(int i = 0; i < 5; i++)
for(int j = 0; j < 9; j++)p[i][j] = ' ';
memset(v, 0, sizeof(v));
}
bool input()
{
for(int i = 0; i < 5; i++)
{
gets(Map[i]);
if(Map[i][0] == '0')return false;
}
return true;
}
bool judge()
{
for(int i = 0; i < 5; i++)
for(int j = 0; j < 9; j++)if(Map[i][j] != p[i][j])return false;
return true;
}
bool dfs(int step)
{
if(judge())return true;
if(step >= 6)return false;
char p2[10][20];
memcpy(p2, p, sizeof(p));///把原来的p存在p2中,待会p回溯时再将p变回来
for(int i = 0; i < 9; i++)///总共九种放法,直接枚举
{
if(v[i])continue;///如果某种放法已经放过,跳过
v[i] = 1;
int x = i / 3;
int y = 2 * (i % 3);///x,y为左上角空格位置
/// *_ _
/// | |
/// |_ _|(这是题目的正方形,*所在的位置就为x,y的位置,此处应为空格)
p[x][y + 1] = p[x][y + 3] = p[x + 2][y + 1] = p[x + 2][y + 3] = '_';///这里是下划线
p[x + 1][y] = p[x + 1][y + 4] = p[x + 2][y] = p[x + 2][y + 4] = '|';
p[x + 1][y + 1] = p[x + 1][y + 2] = p[x + 1][y + 3] = p[x + 2][y + 2] = ' ';
if(dfs(step + 1))return true;
v[i] = 0;
memcpy(p, p2, sizeof(p2));
}
return false;
}
int main()
{
int cases = 0;
while(input())
{
init();
printf("Case %d: ",++cases);
if(dfs(0))cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}