url: https://oj.xtu.edu.cn/problem.php?cid=1007&pid=3
拼图#
题目描述#
每一块拼图可以旋转,但是不能翻转(背面没图案);每个拼图有四条边,边有不同的形状。
我们用英文字母表示边的形状,如果两个拼图的边正好是对应的大小写,那么这两个拼图,就可以拼起来。
那么给你四块拼图,能否拼成一个2×2的拼图。
输入格式#
第一行是一个整数T (1≤T≤1000),表示测试用例的数量。
每个样例是四行,每行是四个字符组成的字符串,表示拼图按顺时钟的边的形状。
输出格式#
依次输出每个样例的结果,如果可以,输出“Yes”;否则输出“No”。
样例输入#
2
abab
ABaa
AAAA
aaaa
AAAA
BBBB
CCCC
DDDD
样例输出#
Yes
No
样例解释#
第一个样例,可以按
A | b
A A|a a
A | b
-----+------
a | B
a a|A a
a | a
拼成。
解题思路:数据范围小,用回溯算法暴力遍历拼图块的顺序和方向。
#include <stdio.h>
#include <string.h>
int used[4];
char pieces[4][5];
char oc_pieces[4][5];
char trans(char c)
{
return (c >= 'a' && c <= 'z') ? c - 32 : c + 32;
}
//void rotate(char oc_pieces[]) {
// char t = oc_pieces[3];
// for (int i = 3; i > 0; i--) {
// oc_pieces[i] = oc_pieces[i - 1];
// }
// oc_pieces[0] = t;
//}
void rotate(char oc_pieces[])
{
char t = oc_pieces[0];
for (int i = 0; i < 3; i++)
{
oc_pieces[i] = oc_pieces[i + 1];
}
oc_pieces[3] = t;
}
int match()
{
if (oc_pieces[0][1] == trans(oc_pieces[1][3]) &&
oc_pieces[1][2] == trans(oc_pieces[2][0]) &&
oc_pieces[2][3] == trans(oc_pieces[3][1]) &&
oc_pieces[3][0] == trans(oc_pieces[0][2]))
{
return 1;
}
else
{
return 0;
}
}
//check用于检查某个拼图块排列能否通过旋转拼图块拼上,可直接for循环,也可递归
int for_check()
{
for (int i = 0; i < 4; i++)
{
rotate(oc_pieces[0]);
for (int j = 0; j < 4; j++)
{
rotate(oc_pieces[1]);
for (int k = 0; k < 4; k++)
{
rotate(oc_pieces[2]);
for (int m = 0; m < 4; m++)
{
rotate(oc_pieces[3]);
if (match())
{
return 1;
}
}
}
}
}
return 0;
}
//int dfs_check(int Idx)
//{
// if (Idx == 4)
// {
// return match() ? 1 : 0;
// }
// for (int r = 0; r < 4; r++)
// {
// if (dfs_check(Idx + 1)) return 1;
// rotate(oc_pieces[Idx]);
// }
// return 0;
//}
//通过回溯算法生成拼图块全排列,oc_pieces用于暂时存储order certain的拼图块。
int dfs(int deep)
{
if (deep == 4)
{
return for_check();
// return dfs_check(0);
}
for (int i = 0; i < 4; i++)
{
if (!used[i])
{
used[i] = 1;
strcpy(oc_pieces[deep], pieces[i]);
if (dfs(deep + 1)) return 1;
used[i] = 0;
}
}
return 0;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
memset(used, 0, sizeof(used));
for (int i = 0; i < 4; i++)
{
scanf("%s", pieces[i]);
}
if (dfs(0)) printf("Yes\n");
else printf("No\n");
}
return 0;
}