L-shapes题解

题目描述

An L-shape is a figure on gridded paper that looks like the first four pictures below. An L-shape contains exactly three shaded cells (denoted by *), which can be rotated in any way.

You are given a rectangular grid. Determine if it contains L-shapes only, where L-shapes can't touch an edge or corner. More formally:

  • Each shaded cell in the grid is part of exactly one L-shape, and
  • no two L-shapes are adjacent by edge or corner.

For example, the last two grids in the picture above do not satisfy the condition because the two L-shapes touch by corner and edge, respectively.

输入格式

The input consists of multiple test cases. The first line contains an integer t ( 1≤t≤100 ) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers n and m ( 1≤n,m≤50 ) — the number of rows and columns in the grid, respectively.

Then n lines follow, each containing m characters. Each of these characters is either '.' or '*' — an empty cell or a shaded cell, respectively.

输出格式

For each test case, output "YES" if the grid is made up of L-shape that don't share edges or corners, and "NO" otherwise.

You can output the answer in any case (for example, the strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive answer).

题意翻译

L形在网格纸上形如下面的前四张图片。L形正好包含三个阴影单元(用*表示),可以以任何方式旋转。

现给你一个矩形网格。确定它是否仅包含L形,其中L形不能接触边或角,也就是说网格中的每个阴影单元正好是一个L形的一部分,并且没有两个L形通过边或角相邻。

例如,上图中的最后两个网格不满足条件,因为两个L形分别通过角和边缘接触。

如果网格满足条件,则输出“YES”,否则输出“NO”。

输入输出样例

输入 #1复制

10
6 10
........**
.**......*
..*..*....
.....**...
...*.....*
..**....**
6 10
....*...**
.**......*
..*..*....
.....**...
...*.....*
..**....**
3 3
...
***
...
4 4
.*..
**..
..**
..*.
5 4
.*..
**..
....
..**
..*.
3 2
.*
**
*.
2 3
*..
.**
3 2
..
**
*.
3 3
.**
*.*
**.
3 3
..*
.**
..*

输出 #1复制

YES
NO
NO
NO
YES
NO
NO
YES
NO
NO

 

#include <stdio.h>
#include <string.h>

#define N 55
#define YES "YES"
#define NO "NO"

char a[N][N];
int st[N][N];
int tot, n, m, dx[] = {1, -1, 0, 0, -1, -1, 1, 1}, dy[] = {0, 0, 1, -1, -1, 1, -1, 1}, chg[5];

void dfs(int x, int y, int tm) {
    st[x][y] = 1;
    ++tot;
    if (tot > 3) return;
    for (int i = 0; i < (tm ? 8 : 4); ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx < 0 || nx >= n || ny < 0 || ny >= m || a[nx][ny] == '.' || st[nx][ny]) continue;
        if (!tm) chg[tot] = i;
        dfs(nx, ny, tm);
        if (tot > 3) return;
    }
}

int main() {
    int _;
    scanf("%d", &_);
    while (_--) {
        int f = 1;
        memset(st, 0, sizeof st);
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; ++i) scanf("%s", a[i]);
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j)
                if (a[i][j] == '*' && !st[i][j]) {
                    tot = 0;
                    dfs(i, j, 0);
                    if (tot != 3 || chg[1] == chg[2]) {
                        f = 0;
                        break;
                    }
                }
            if (!f) break;
        }
        if (!f) {
            printf("%s\n", NO);
            continue;
        }
        memset(st, 0, sizeof st);
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j)
                if (a[i][j] == '*' && !st[i][j]) {
                    tot = 0;
                    dfs(i, j, 1);
                    if (tot != 3) {
                        f = 0;
                        break;
                    }
                }
            if (!f) break;
        }
        printf("%s\n", f ? YES : NO);
    }
    return 0;
}

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值