【搜索】【NOI2005】智慧珠游戏



【输入格式】
文件中包含初始的盘件描述,一共有 10 行,第 i 行有 i 个字符。如果第 i 行的第 j 个字符是字母”A”至”L”中的一个,则表示第 i 行第 j 列的格子上已经放了零件,零件的编号为对应的字母。如果第 i 行的第 j 个字符是”.”,则表示第 i 行第 j 列的格子上没有放零件。
输入保证预放的零件已摆放在盘件中。
【输出格式】
如果能找到解,向输出文件打印 10 行,为放完全部 12 个零件后的布局。其中,第 i 行应包含 i 个字符,第 i 行的第 j 个字符表示第 i 行第 j 列的格子上放的是哪个零件。
如果无解,输出单独的一个字符串‘No solution’(不要引号,请注意大小写)。
所有的数据保证最多只有一组解。
【输入样例】
.
..
...
....
.....
.....C
...CCC.
EEEHH...
E.HHH....
E.........
【输出样例】
B
BK
BKK
BJKK
JJJDD
GJGDDC
GGGCCCI
EEEHHIIA
ELHHHIAAF
ELLLLIFFFF
只能说,此题已经恶心到了一定境界了……
把A到L的各种状态的坐标变换全部打出来(这几乎是此题最难的地方!)(把每个零件每种状态中第一个枚举到的点作为基准,并且算出其他点的相对坐标),然后就是搜索模块……

搜索之前先预处理一下,把明显不可能的情况(任何一个零件都放不进去的情况)直接排除,就可以将第5组的No solution排除了。
代码就略显壮观了……

/****************************\
 * @prob: NOI2005 zhzyx     *
 * @auth: Wang Junji        *
 * @stat: Accepted.         *
 * @date: June. 3rd, 2012   *
 * @memo: 搜索、超级预处理    *
\****************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>

struct chess
{
    int sz, cnt, x[8][5], y[8][5]; chess(): sz(0), cnt(0) {memset(x, 0, sizeof x); memset(y, 0, sizeof y);}
    chess(int &X)
    {
        switch (X)
        {
        case 'A': cnt = 4, sz = 2; 
           x[0][0] = 1, y[0][0] = 0; x[0][1] = 0, y[0][1] = 1;
           x[1][0] = 1, y[1][0] = 0; x[1][1] = 1, y[1][1] = 1;
           x[2][0] = 0, y[2][0] = 1; x[2][1] = 1, y[2][1] = 1;
           x[3][0] = 1, y[3][0] = 0; x[3][1] = 1, y[3][1] =-1;
           break;
        case 'B': cnt = 2, sz = 3;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 0, y[0][1] = 2; x[0][2] = 0, y[0][2] = 3;
           x[1][0] = 1, y[1][0] = 0; x[1][1] = 2, y[1][1] = 0; x[1][2] = 3, y[1][2] = 0;
           break;
        case 'C': cnt = 8, sz = 3;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 0, y[0][1] = 2; x[0][2] = 1, y[0][2] = 0;
           x[1][0] = 0, y[1][0] = 1; x[1][1] = 1, y[1][1] = 1; x[1][2] = 2, y[1][2] = 1;
           x[2][0] = 1, y[2][0] =-2; x[2][1] = 1, y[2][1] =-1; x[2][2] = 1, y[2][2] = 0;
           x[3][0] = 1, y[3][0] = 0; x[3][1] = 2, y[3][1] = 0; x[3][2] = 2, y[3][2] = 1;
           x[4][0] = 1, y[4][0] = 0; x[4][1] = 2, y[4][1] = 0; x[4][2] = 2, y[4][2] =-1;
           x[5][0] = 1, y[5][0] = 0; x[5][1] = 1, y[5][1] = 1; x[5][2] = 1, y[5][2] = 2;
           x[6][0] = 0, y[6][0] = 1; x[6][1] = 1, y[6][1] = 0; x[6][2] = 2, y[6][2] = 0;
           x[7][0] = 0, y[7][0] = 1; x[7][1] = 0, y[7][1] = 2; x[7][2] = 1, y[7][2] = 2;
           break;
        case 'D': cnt = 1, sz = 3;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 1, y[0][1] = 0; x[0][2] = 1, y[0][2] = 1; break;
        case 'E': cnt = 4, sz = 4;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 0, y[0][1] = 2; x[0][2] = 1, y[0][2] = 0; x[0][3] = 2, y[0][3] = 0;
           x[1][0] = 1, y[1][0] = 0; x[1][1] = 2, y[1][1] = 0; x[1][2] = 2, y[1][2] = 1; x[1][3] = 2, y[1][3] = 2;
           x[2][0] = 0, y[2][0] = 1; x[2][1] = 0, y[2][1] = 2; x[2][2] = 1, y[2][2] = 2; x[2][3] = 2, y[2][3] = 2;
           x[3][0] = 2, y[3][0] =-2; x[3][1] = 2, y[3][1] =-1; x[3][2] = 2, y[3][2] = 0; x[3][3] = 1, y[3][3] = 0;
           break;
        case 'F': cnt = 8, sz = 4;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 1, y[0][1] = 1; x[0][2] = 0, y[0][2] = 2; x[0][3] = 0, y[0][3] = 3;
           x[1][0] = 1, y[1][0] = 0; x[1][1] = 2, y[1][1] = 0; x[1][2] = 3, y[1][2] = 0; x[1][3] = 2, y[1][3] = 1;
           x[2][0] = 1, y[2][0] =-2; x[2][1] = 1, y[2][1] =-1; x[2][2] = 1, y[2][2] = 0; x[2][3] = 1, y[2][3] = 1;
           x[3][0] = 1, y[3][0] =-1; x[3][1] = 1, y[3][1] = 0; x[3][2] = 2, y[3][2] = 0; x[3][3] = 3, y[3][3] = 0;
           x[4][0] = 1, y[4][0] = 0; x[4][1] = 1, y[4][1] = 1; x[4][2] = 2, y[4][2] = 0; x[4][3] = 3, y[4][3] = 0;
           x[5][0] = 1, y[5][0] =-1; x[5][1] = 1, y[5][1] = 0; x[5][2] = 1, y[5][2] = 1; x[5][3] = 1, y[5][3] = 2;
           x[6][0] = 1, y[6][0] = 0; x[6][1] = 2, y[6][1] = 0; x[6][2] = 1, y[6][2] =-1; x[6][3] = 3, y[6][3] = 0;
           x[7][0] = 0, y[7][0] = 1; x[7][1] = 0, y[7][1] = 2; x[7][2] = 1, y[7][2] = 2; x[7][3] = 0, y[7][3] = 3;
           break;
        case 'G': cnt = 4, sz = 4;
           x[0][0] = 1, y[0][0] = 0; x[0][1] = 0, y[0][1] = 1; x[0][2] = 0, y[0][2] = 2; x[0][3] = 1, y[0][3] = 2;
           x[1][0] = 0, y[1][0] = 1; x[1][1] = 1, y[1][1] = 0; x[1][2] = 2, y[1][2] = 0; x[1][3] = 2, y[1][3] = 1;
           x[2][0] = 1, y[2][0] = 0; x[2][1] = 1, y[2][1] = 1; x[2][2] = 1, y[2][2] = 2; x[2][3] = 0, y[2][3] = 2;
           x[3][0] = 0, y[3][0] = 1; x[3][1] = 1, y[3][1] = 1; x[3][2] = 2, y[3][2] = 1; x[3][3] = 2, y[3][3] = 0;
           break;
        case 'H': cnt = 8, sz = 4;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 1, y[0][1] = 0; x[0][2] = 1, y[0][2] = 1; x[0][3] = 0, y[0][3] = 2;
           x[1][0] = 1, y[1][0] = 1; x[1][1] = 1, y[1][1] = 0; x[1][2] = 2, y[1][2] = 1; x[1][3] = 2, y[1][3] = 0;
           x[2][0] = 0, y[2][0] = 1; x[2][1] = 1, y[2][1] = 0; x[2][2] = 1, y[2][2] = 1; x[2][3] = 1, y[2][3] =-1;
           x[3][0] = 0, y[3][0] = 1; x[3][1] = 1, y[3][1] = 0; x[3][2] = 1, y[3][2] = 1; x[3][3] = 2, y[3][3] = 1;
           x[4][0] = 0, y[4][0] = 1; x[4][1] = 1, y[4][1] = 0; x[4][2] = 1, y[4][2] = 1; x[4][3] = 2, y[4][3] = 0;
           x[5][0] = 0, y[5][0] = 1; x[5][1] = 1, y[5][1] = 0; x[5][2] = 1, y[5][2] = 1; x[5][3] = 1, y[5][3] = 2;
           x[6][0] = 1, y[6][0] =-1; x[6][1] = 1, y[6][1] = 0; x[6][2] = 2, y[6][2] =-1; x[6][3] = 2, y[6][3] = 0;
           x[7][0] = 0, y[7][0] = 1; x[7][1] = 0, y[7][1] = 2; x[7][2] = 1, y[7][2] = 1; x[7][3] = 1, y[7][3] = 2;
           break;
        case 'I': cnt = 8, sz = 4;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 0, y[0][1] = 2; x[0][2] = 1, y[0][2] = 2; x[0][3] = 1, y[0][3] = 3;
           x[1][0] = 1, y[1][0] =-1; x[1][1] = 1, y[1][1] = 0; x[1][2] = 2, y[1][2] =-1; x[1][3] = 3, y[1][3] =-1;
           x[2][0] = 0, y[2][0] = 1; x[2][1] = 1, y[2][1] = 1; x[2][2] = 1, y[2][2] = 2; x[2][3] = 1, y[2][3] = 3;
           x[3][0] = 1, y[3][0] = 0; x[3][1] = 2, y[3][1] = 0; x[3][2] = 2, y[3][2] =-1; x[3][3] = 3, y[3][3] =-1;
           x[4][0] = 1, y[4][0] = 0; x[4][1] = 2, y[4][1] = 0; x[4][2] = 2, y[4][2] = 1; x[4][3] = 3, y[4][3] = 1;
           x[5][0] = 1, y[5][0] =-2; x[5][1] = 1, y[5][1] =-1; x[5][2] = 1, y[5][2] = 0; x[5][3] = 0, y[5][3] = 1;
           x[6][0] = 1, y[6][0] = 0; x[6][1] = 1, y[6][1] = 1; x[6][2] = 2, y[6][2] = 1; x[6][3] = 3, y[6][3] = 1;
           x[7][0] = 1, y[7][0] = 0; x[7][1] = 1, y[7][1] =-1; x[7][2] = 0, y[7][2] = 1; x[7][3] = 0, y[7][3] = 2;
           break;
        case 'J': cnt = 1, sz = 4;
           x[0][0] = 1, y[0][0] =-1; x[0][1] = 1, y[0][1] = 0; x[0][2] = 1, y[0][2] = 1; x[0][3] = 2, y[0][3] = 0; break;
        case 'K': cnt = 4, sz = 4;
           x[0][0] = 1, y[0][0] = 0; x[0][1] = 1, y[0][1] = 1; x[0][2] = 2, y[0][2] = 1; x[0][3] = 2, y[0][3] = 2;
           x[1][0] = 1, y[1][0] = 0; x[1][1] = 1, y[1][1] =-1; x[1][2] = 2, y[1][2] =-1; x[1][3] = 2, y[1][3] =-2;
           x[2][0] = 0, y[2][0] = 1; x[2][1] = 1, y[2][1] = 1; x[2][2] = 1, y[2][2] = 2; x[2][3] = 2, y[2][3] = 2;
           x[3][0] = 0, y[3][0] = 1; x[3][1] = 1, y[3][1] = 0; x[3][2] = 1, y[3][2] =-1; x[3][3] = 2, y[3][3] =-1;
           break;
        case 'L': cnt = 8, sz = 4;
           x[0][0] = 0, y[0][0] = 1; x[0][1] = 0, y[0][1] = 2; x[0][2] = 0, y[0][2] = 3; x[0][3] = 1, y[0][3] = 0;
           x[1][0] = 0, y[1][0] = 1; x[1][1] = 1, y[1][1] = 1; x[1][2] = 2, y[1][2] = 1; x[1][3] = 3, y[1][3] = 1;
           x[2][0] = 1, y[2][0] = 0; x[2][1] = 1, y[2][1] =-1; x[2][2] = 1, y[2][2] =-2; x[2][3] = 1, y[2][3] =-3;
           x[3][0] = 1, y[3][0] = 0; x[3][1] = 2, y[3][1] = 0; x[3][2] = 3, y[3][2] = 0; x[3][3] = 3, y[3][3] = 1;
           x[4][0] = 1, y[4][0] = 0; x[4][1] = 2, y[4][1] = 0; x[4][2] = 3, y[4][2] = 0; x[4][3] = 3, y[4][3] =-1;
           x[5][0] = 1, y[5][0] = 0; x[5][1] = 1, y[5][1] = 1; x[5][2] = 1, y[5][2] = 2; x[5][3] = 1, y[5][3] = 3;
           x[6][0] = 1, y[6][0] = 0; x[6][1] = 2, y[6][1] = 0; x[6][2] = 3, y[6][2] = 0; x[6][3] = 0, y[6][3] = 1;
           x[7][0] = 0, y[7][0] = 1; x[7][1] = 0, y[7][1] = 2; x[7][2] = 0, y[7][2] = 3; x[7][3] = 1, y[7][3] = 3;
           break;
        }
    }
} ch[128]; bool marked[128]; char mp[20][20];

inline bool check(int x, int y, chess &c, int k)
{
    for (int t = 0; t < c.sz; ++t)
    if (x + c.x[k][t] < 1 || y + c.y[k][t] < 1 ||
        mp[x + c.x[k][t]][y + c.y[k][t]] - '.')
        return 0;
    return 1;
}

inline void set(int x, int y, int K, int k)
{
    for (int t = 0; t < ch[K].sz; ++t)
        mp[x + ch[K].x[k][t]][y + ch[K].y[k][t]] = K;
    return;
}

inline void reset(int x, int y, chess &c, int k)
{
    for (int t = 0; t < c.sz; ++t)
        mp[x + c.x[k][t]][y + c.y[k][t]] = '.';
    return;
}

inline bool valid()
{
    for (int i = 1; i < 11; ++i)
    for (int j = 1; j < i + 1; ++j)
    {
        if (mp[i][j] == '.' &&
            mp[i - 1][j] - '.' && mp[i][j - 1] - '.' &&
            mp[i + 1][j] - '.' && mp[i][j + 1] - '.')
            return 0;
        if (mp[i][j] == '.' && mp[i][j + 1] == '.' &&
            mp[i][j - 1] - '.' && mp[i][j + 2] - '.' &&
            mp[i - 1][j] - '.' && mp[i - 1][j + 1] - '.' &&
            mp[i + 1][j] - '.' && mp[i + 1][j + 1] - '.')
            return 0;
        if (mp[i][j] == '.' && mp[i + 1][j] == '.' &&
            mp[i - 1][j] - '.' && mp[i + 2][j] - '.' &&
            mp[i][j - 1] - '.' && mp[i + 1][j - 1] - '.' &&
            mp[i][j + 1] - '.' && mp[i + 1][j + 1] - '.')
            return 0;
    }
    return 1;
}

void Dfs(int i, int j)
{
    if (j > i) ++i, j = 1;
    if (i > 10)
    {
        for (int I = 1; I < 11; ++I) printf("%s\n", mp[I] + 1);
        exit(0);
    }
    if (mp[i][j] - '.') Dfs(i, j + 1);
    else for (int k = 'L'; k > 'A' - 1; --k)
    if (!marked[k])
    {
        marked[k] = 1; mp[i][j] = k;
        for (int t = 0; t < ch[k].cnt; ++t)
        if (check(i, j, ch[k], t))
            set(i, j, k, t), Dfs(i, j + 1), reset(i, j, ch[k], t);
        mp[i][j] = '.'; marked[k] = 0;
    }
    return;
}

int main()
{
    freopen("zhzyx.in", "r", stdin);
    freopen("zhzyx.out", "w", stdout);
    for (int i = 1; i < 11; ++i) scanf("%s", mp[i] + 1);
    for (int i = 1; i < 11; ++i)
    for (int j = 1; j < i + 1; ++j)
        if (isupper(mp[i][j])) marked[(int)mp[i][j]] = 1;
    for (int i = 'A'; i < 'L' + 1; ++i) ch[i] = chess(i);
    if (!valid()) {printf("No solution\n"); return 0;}
    Dfs(1, 1); printf("No solution\n"); return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值