具体题目详见 NOI2005 第一试试题。
这显然是一个 NP 问题。怎么做呢?答案很明显,搜索。
说到搜索,这道题所要求的并不是最优解,也不是方案数,而且数据保证如果有解则只有一组解。
然后再对照这个题目:用所有的“智慧珠”来填满棋盘中每一个空。
想到了什么?对,精确覆盖模型。用每一个智慧珠和棋盘中的每一空为列,以智慧珠翻转和旋转所得的 60 个形态在每一个位置上的填补为行,即可。
顺便说一句,这个预处理的恶心程度是不能和【靶形数独】同日而语的。
所剩的问题就只有 DLX 了。几乎所有数据 0.00s。
Code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <iostream>
#include <algorithm>
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;
#define swap(a, b, t) ({t _ = (a); (a) = (b); (b) = _;})
#define MAX(a, b, t) ({t _ = (a), __ = (b); _ > __ ? _ : __;})
#define MIN(a, b, t) ({t _ = (a), __ = (b); _ < __ ? _ : __;})
typedef int MAINTYPE;
#define max(a, b) MAX(a, b, MAINTYPE)
#define min(a, b) MIN(a, b, MAINTYPE)
#define maxs 5
#define maxn 12
#define maxz 60
#define maxv 100005
const int width[maxn] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int zhz[maxz + 2][maxs + 2][2] =
{
{
{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
{
{3, 1}, {0, 0}, {1, 0}, {0, 1}, {0, 0}, {0, 0}},
{
{3, 1}, {0, 0}, {0, 1}, {-1, 0}, {0, 0}, {0, 0}},
{
{3, 1}, {0, 0}, {-1, 0}, {0, -1}, {0, 0}, {0, 0}},
{
{3, 1}, {0, 0}, {0, -1}, {1, 0}, {0, 0}, {0, 0}},
{
{4, 2}, {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 0}},
{
{4, 2}, {0, 0}, {-1, 0}, {-2, 0}, {-3, 0}, {0, 0}},
{
{4, 3}, {0, 0}, {1, 0}, {0, 1}, {0, 2}, {0, 0}},
{
{4, 3}, {0, 0}, {0, 1}, {-1, 0}, {-2, 0}, {0, 0}},
{
{4, 3}, {0, 0}, {-1, 0}, {0, -1}, {0, -2}, {0, 0}},
{
{4, 3}, {0, 0