2021-04 CSP真题

本文介绍了2021年CSP竞赛中的几道题目,包括灰度直方图的计算、邻域均值的处理、DHCP服务器的工作原理以及疫苗运输的优化问题。通过这些题目,探讨了图像处理的基础算法和网络服务中的关键概念,同时展示了动态规划和预处理因数在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

2021-04 CSP真题

1. 灰度直方图

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <vector>
#define fora(i, a, b) for(int i = a; i <= b; i++)
#define fors(i, a, b) for(int i = a; i >= b; i--)
using namespace std;
int n, m, l;
int a[800][800], ll[800];
int main() {
    memset(ll, 0, sizeof(ll));
    scanf("%d%d%d", &n, &m, &l);
    fora(i, 0, n - 1){
        fora(j, 0, m - 1){
            scanf("%d", &a[i][j]);
            ll[a[i][j]]++;
        }
    }
    fora(i, 0, l - 1){
        printf("%d ", ll[i]);
    }
    return 0;
}

2. 邻域均值

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <vector>
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
using namespace std;
int n, l, r, t;
int a[610][610], sum[605][605], sq[605][605], ans = 0;
bool AC1(int i, int j){
    int minx = max(0, i - r);
    int maxx = min(n - 1, i + r);
    int miny = max(0, j - r);
    int maxy = min(n - 1, j + r);
    sq[i][j] = (maxx - minx + 1)*(maxy - miny + 1);
    
    if(sum[i][j - 1] != -1 && i >= 1){
        sum[i][j] = sum[i][j-1];
        rep(k, minx, maxx){
            if(j + r <= n - 1) sum[i][j] += a[k][maxy];
            if(j - r - 1 >= 0) sum[i][j] -= a[k][miny - 1];
        }
    }
    else{
        sum[i][j] = 0;
        rep(p, minx, maxx)
            rep(q, miny, maxy) sum[i][j] += a[p][q];
    }
    if(sum[i][j] <= t * sq[i][j]) return 1;
    else return 0;
}

int main() {
    memset(sum, -1, sizeof(sum));
    scanf("%d%d%d%d", &n, &l, &r, &t);
    rep(i, 0, n - 1)
        rep(j, 0, n - 1) scanf("%d", &a[i][j]);
    rep(i, 0, n - 1)
        rep(j, 0, n - 1){
            if(AC1(i, j)) ans++;
        }
    printf("%d", ans);
    return 0;
}

3. DHCP服务器


4. 校门外的树

  • 校门外的树

  • 知识点:预处理因数,动态规划

  • 思路:需要找到转移方程,对于第 i i i 个障碍物,依次查找其前面的障碍物 j j j 与其成对,再在 a [ i ] − a [ j ] a[i]-a[j] a[i]a[j] 中遍历因数是否重复计算或不满足条件。

#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
const int N = 1e3 + 5;
const int mod = 1e9 + 7;
using namespace std;
int n, a[N], flg[100005];
ll dp[N];
vector<int> factor[100005];
void init(){  //预处理每个数字的因数
    rep(i, 1, a[n] / 2)
        for(int multi = 2; multi * i <= a[n]; multi++) 
            factor[multi * i].push_back(i);
}
int main(){
    cin >> n;
    rep(i, 1, n) cin >> a[i];
    init();
    dp[1] = 1;
    rep(i, 2, n){
        memset(flg, 0, sizeof(flg));
        per(j, i - 1, 1){
            int d = a[i] - a[j], cnt = 0;
            for(auto k : factor[d])  //遍历因数
                if(!flg[k]){
                    cnt++;
                    flg[k] = 1;
                }
            flg[d] = 1;
            (dp[i] += (dp[j] * cnt)) %= mod;
        }
    }
    cout << dp[n] << endl;
}
/*
11
0 10 20 30 40 50 60 70 80 90 100
*/

5. 疫苗运输

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值