USACO历年青铜组真题解析 | 2023年2月Stamp Grid

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考青铜组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年青铜组真题解析 | 汇总-CSDN博客


邮票画是在 N×N 画布上的黑白画,其中某些单元被涂上墨水,而其他单元则是空白。它可以用一个 N×N 的字符数组来描述 (1≤N≤20)。如果画布在该方格含有墨水,则数组中第i行的第j列为 *,否则等于 .。

Bessie有一幅邮票画,她想创作,所以农夫John借给她一张 K×K(1≤KN) 的邮票来做,还有一张空的 N×N 的帆布。Bessie可以重复地将邮票顺时针旋转90∘90∘ 。并在网格上的任何地方涂墨,只要涂墨的地方完全在网格内。为了涂墨,Bessie选择整数 i,j ,使 i∈[1,NK+1] and j∈[1,NK+1];对于每一个 (i′,j′) 使 1≤i′,j′≤K

Bessie可以在两次盖章之间的任何时候旋转印章。一旦邮票画被涂成黑色,它就一直是黑色的。

农民John想知道Bessie是否有可能用他的邮票创造出她想要的邮票画。对于 T(1≤T≤100) 的每一个测试案例,帮助农夫John回答这个问题。

【输入】

The first line of input contains T, the number of test cases.

Each test case starts with an integer N followed by N lines, each containing a string of *s and .s, representing Bessie's desired stamp painting. The next line contains K and is followed by K lines, each containing a string of *s and .s, representing Farmer John's stamp.

Consecutive test cases are separated by newlines.

【输出】

扫描二维码关注公众号,回复: 17161525 查看本文章

For each test case, output YES or NO on separate lines.

【输入样例】

4

2
**
*.
1
*

3
.**
.**
***
2
.*
**

3
...
.*.
...
3
.*.
...
...

3
**.
.**
..*
2
.*
*.

【输出样例】

YES
YES
NO
YES

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int t, n, k;
char a1[25][25], a2[25][25], b1[25][25], b2[25][25], b3[25][25], b4[25][25];
void paint(char a[][25], char b[][25], char a2[][25])  // 定义对比并画画的自定义函数
{
    for (int i=0; i<n-k+1; i++) {  // a1矩阵的顶点坐标i和j,从0 - n-k+1
        for (int j=0; j<n-k+1; j++) {
            int mark = 1;  // 定义标记位mark,初始为1
            for (int x=i; x<i+k; x++) {  // 遍历画布中邮票大小的区域
                for (int y=j; y<j+k; y++) {
                    if (b[x-i][y-j]=='*' && a[x][y]!='*') {  // 该区域与邮票对比(使用x-i和y-j,保证邮票的坐标永远是0,0 0,1 1,0 1,1),对于邮票中的'*',如果目的邮票画对应的位置也为'*'
                        mark = 0;  // 修改标记位为0
                        break;  // 退出循环
                    }
                }
                if (mark==0) break;  // 如果mark为0,退出循环
            }
            if (mark == 1) {  // 如果mark为1
                for (int x = i; x<i+k; x++) {  // 遍历画布中邮票大小的区域
                    for (int y=j; y<j+k; y++) {
                        if (b[x-i][y-j]=='*' && a2[x][y]=='.') {  // 对于邮票涂墨且画布中空白的地方
                            a2[x][y] = b[x-i][y-j];  //在画布的对应位置涂成黑色
                        }
                    }
                }
            }
        }
    }
}
int main()
{
    cin >> t;  // 输入t组数据
    while (t--) {  // 遍历t组数据
        cin >> n;  // 输入n
        for (int i=0; i<n; i++) {  // 输入n*n的邮票画
            for (int j=0; j<n; j++) {
                cin >> a1[i][j];
            }
        }
        cin >> k;  // 输入k
        for (int i=0; i<k; i++) {  // 输入k*k的邮票
            for (int j=0; j<k; j++) {
                cin >> b1[i][j];
            }
        }
        for (int i=0; i<k; i++) {  // 旋转90度
            for (int j=0; j<k; j++) {
                b2[i][j] = b1[k-1-j][i];
            }
        }
        for (int i=0; i<k; i++) {  // 再旋转90度(相当于原有邮票旋转180度)
            for (int j=0; j<k; j++) {
                b3[i][j] = b2[k-1-j][i];
            }
        }
        for (int i=0; i<k; i++) {  // 再旋转90度(相当于原有邮票旋转270度)
            for (int j=0; j<k; j++) {
                b4[i][j] = b3[k-1-j][i];
            }
        }
        memset(a2, '.', sizeof(a2));  // 每次初始化n*n的画布
        
        paint(a1, b1, a2);  // 用b1去比对a1,并画画
        paint(a1, b2, a2);  // 用b2去比对a1,并画画
        paint(a1, b3, a2);  // 用b3去比对a1,并画画
        paint(a1, b4, a2);  // 用b4去比对a1,并画画
        
        int mark = 0;  // 定义mark标记位
        for (int i=0; i<n; i++) {  // 检查a1与a2是否完全匹配
            for (int j=0; j<n; j++) {
                if (a1[i][j]==a2[i][j]) mark = 1;  // 匹配时mark标记为1
                else {
                    mark = 0;  // 如果遇到有个不匹配的,mark修改为0
                    break;  // 并退出循环
                }
            }
            if (mark==0) break;  // 如果mark为0,再退出外部循环
        }
        if (mark==1) cout << "YES" << endl;  // 最后mark为1就输出YES
        else cout << "NO" << endl;  // 否则输出NO
    }
    return 0;
}

【运行结果】

4

2
**
*.
1
*
YES

3
.**
.**
***
2
.*
**
YES

3
...
.*.
...
3
.*.
...
...
NO

3
**.
.**
..*
2
.*
*.
YES

猜你喜欢

转载自blog.csdn.net/guolianggsta/article/details/134888521
今日推荐