【CSP】202206-2 寻宝!大冒险! 满分解法(仅供参考)

试题编号: 202206-2
试题名称: 寻宝!大冒险!
时间限制: 500ms
内存限制: 512.0MB

需要注意的细节:

  • 数据范围

在这里插入图片描述
地图a如果用数组存储,范围过大,容易溢出,尽量不存储或用其他方式,如vector。
藏宝图b范围较小,可以用数组直接存储。

  • 数组b的输入顺序

在这里插入图片描述
在这里插入图片描述

  • 越界问题

在这里插入图片描述

由此可知,可以认为每颗树都可以作为藏宝图的左下角位置。
依次遍历所有的树并判断是否可以为藏宝位置。

简单的判断方式:比较矩阵内的所有点的bool值是否相等。

n(表示输入的点数)、L(表示平面的边长)、S(表示模式的边长)和 ans(用于存储匹配的次数)。这些变量的类型是 ll,即长整型(long long),以确保能够处理较大的数值。

int main(){
    ll n,L,S,ans=0;
    cin>>n>>L>>S;

接下来,程序定义了一个 map 容器 mp,用于存储输入的点坐标,并将其标记为 true。同时,定义了一个二维布尔数组 b,用于存储模式的布尔矩阵。

map<pair<ll,ll>,bool>mp;
bool b[55][55];

然后,程序通过循环读取 n 个点的坐标,并将这些坐标存储在 map 容器 mp 中。

for(ll i=0;i<n;i++){
    ll x,y;
    cin>>x>>y;
    mp[{x,y}]=1;
}

接下来,程序读取模式矩阵 b 的值。注意,这里是从 S+11 进行读取,以便将模式矩阵倒置存储。

for(ll i=S+1;i>=1;i--)
    for(ll j=1;j<=S+1;j++)
        cin>>b[i][j];

然后,程序遍历 map 容器 mp 中的每个点,并检查以该点为左下角的 S+1 x S+1 区域是否与模式矩阵 b 匹配。具体来说,程序通过嵌套循环遍历模式矩阵的每个元素,并检查对应的平面坐标是否在 map 容器 mp 中存在且值相同。如果有任何一个元素不匹配,则标记 flagfalse 并退出循环。

for(auto it:mp){
    ll x=it.first.first,y=it.first.second;
    bool flag=true;
    for (ll i = 0; i <= S; i++)
    {
        for(ll j=0;j<=S;j++){
            ll xx=x+i,yy=y+j;
            if(xx>L||yy>L||mp[{xx,yy}]!=b[i+1][j+1]){
                flag=false;
                break;
            }
        }
        if(!flag) break;
    }
    if(flag) ans++;
}

最后,程序输出匹配的次数 ans

参考代码

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;

int main() {
    ll n, L, S, ans = 0;
    
    // 读取输入的 n, L, S
    cin >> n >> L >> S;
    
    // 定义一个 map 来存储点的坐标
    map<pair<ll, ll>, bool> mp;
    
    // 定义一个二维数组来存储模板
    bool b[55][55];
    
    // 读取 n 个点的坐标并存储在 map 中
    for (ll i = 0; i < n; i++) {
        ll x, y;
        cin >> x >> y;
        mp[{x, y}] = 1;
    }

    // 读取模板的值,注意模板是倒序读取的
    for (ll i = S + 1; i >= 1; i--)
        for (ll j = 1; j <= S + 1; j++)
            cin >> b[i][j];
   
    // 遍历 map 中的每个点
    for (auto it : mp) {
        ll x = it.first.first, y = it.first.second;
        bool flag = true;
        
        // 检查模板是否匹配
        for (ll i = 0; i <= S; i++) {
            for (ll j = 0; j <= S; j++) {
                ll xx = x + i, yy = y + j;
                
                // 如果超出边界或者不匹配模板,设置 flag 为 false 并跳出循环
                if (xx > L || yy > L || mp[{xx, yy}] != b[i + 1][j + 1]) {
                    flag = false;
                    break;
                }
            }
            if (!flag) break;
        }
        
        // 如果模板匹配,计数器加一
        if (flag) ans++;
    }
    
    // 输出结果
    cout << ans;
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值