hdu 1112

15 篇文章 0 订阅

模拟 注意钥匙的左右边缘不能超过锁的范围 就算是空白也不行


#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define pi acos(-1.0)
#define inf 1<<29
#define INF 0x3f3f3f3f
#define zero 1e-8

using namespace std;

char lock[10507][1207];
char key[127][127];
bool flag[1107][1207];

struct edge {
    int x, y;
} lef[10007], rig[10007], down[10007];

int l, rr, d;
int r, c, n, m;
int depth;
int len;
void todo()
{
    l = 0;
    r = 0;
    d = 0;
    len = 0;

    for (int i = 0; i < rr; ++i)
        for (int j = 0; j < c; ++j) {
            if (key[i][j] == '#') {
                if (j > 0 && key[i][j - 1] == '#') continue;
                lef[l].x = i;
                lef[l++].y = j;

            }
        }
    for (int i = 0; i < rr; ++i)
        for (int j = c - 1; j >= 0; --j) {
            if (key[i][j] == '#') {
                if (j < c - 1 && key[i][j + 1] == '#') continue;
                rig[r].x = i;
                rig[r++].y = j;
            }
        }

    for (int j = 0; j < c; ++j)
        for (int i = rr - 1; i > -1; --i) {
            if (key[i][j] == '#') {
                if (i < rr - 1 && key[i + 1][j] == '#') continue;
                down[d].x = i;
                down[d++].y = j;
            }
        }

}

bool j_left(int x, int y)
{
    for (int i = 0; i < l; ++i)
        if (y < 0 || lock[lef[i].x + x][lef[i].y + y] == '#') {
            return false;
        }

    return true;
}

bool j_right(int x, int y)
{

    for (int i = 0; i < r; ++i) {
        if (c + y > m || lock[rig[i].x + x][rig[i].y + y] == '#') {
            return false;
        }

    }

    return true;
}

bool j_down(int x, int y)
{


    for (int i = 0; i < d; ++i) {

        if (x > n + rr || lock[down[i].x + x][down[i].y + y] == '#') {
            return false;
        }
    }
    return true;
}

void rem(int x, int y)
{

    flag[down[0].x + x][down[0].y + y] = true;
}

bool ifdo(int x, int y)
{

    if (!flag[down[0].x + x][down[0].y + y]) return true;
    return false;

}
void dfs(int x, int y)
{

    if (x > depth) depth = x;
    if (depth == n + rr) return ;
    rem(x, y);

    if (j_down(x + 1, y) && ifdo(x + 1, y)) dfs(x + 1, y);
    if (j_left(x, y - 1) && ifdo(x, y - 1)) dfs(x, y - 1);
    if (j_right(x, y + 1) && ifdo(x, y + 1)) dfs(x, y + 1);

}


int main()
{

    int t;
    cin >> t;
    for (; t--;) {

        scanf("%d %d", &rr, &c);

        for (int i = 0; i < rr; ++i) {
            scanf("%s", key[i]);
        }

        scanf("%d %d", &n, &m);

        memset(lock, '.', sizeof(lock));

        for (int i = rr; i < rr + n; ++i) {
            scanf("%s", lock[i]);
        }


        todo();
        depth = 0;
        if (c > m) {
            printf("The key falls to depth 0.\n");
            continue;
        }
        if (r == 0 && l == 0 && d == 0) {
            printf("The key can fall through.\n");
            continue;
        }

        memset(flag, false, sizeof(flag));

        dfs(0, 0);
        if (depth >= n + rr) printf("The key can fall through.\n");
        else
            printf("The key falls to depth %d.\n", depth);
    }

    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值