CCF-CSP 202203 赛题训练
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF-CSP 202203 赛题训练相关的知识,希望对你有一定的参考价值。
CCF-CSP 202203 赛题训练
未初始化警告
题意:判断等式右边是否在左边出现过,出现过说明赋值过,考虑使用set<>或者数组
都可以。
10 7
1 2
3 3
3 0
3 3
6 2
2 1
8 2
3
样例解释 其中第一、二、五条赋值语句右值未被初始化。
#include <iostream>
using namespace std;
const int N = 1e5+10;
bool q[N];
int n, k;
int x, y;
int res;
int main()
q[0] = 1; // 0为常量
cin >> n >> k;
while (k--)
cin >> x >> y;
if (!q[y]) // 如果右边之前没存在过,便res++
res++;
q[x] = true; // 将左边标记赋值
cout << res << endl;
return 0;
https://blog.csdn.net/weixin_53919192/article/details/124872609?spm=1001.2014.3001.5502
出行计划
暴力解法:给出每次核酸时间,遍历查询能否通行?
出行开始时间t
满足:[q+k, q+k+c-1]
:即核酸报告结果出来时间,及地点核酸要求期限。
#include<bits/stdc++.h>
using namespace std;
struct plan
int t, c;
p[100000+1];
int main()
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <=n; i++)
cin >> p[i].t >> p[i].c;
while (m--)
int q;
cin >> q;
int cnt = 0;
for (int i = 1; i <= k; i++)
if (q+k <= p[i].t && p[i].t <= (q+k+p[i].c-1))
cnt++;
cout << cnt << endl;
数组a:a[1], a[2], a[3], a[n]
数组b : b[1] ,b[2] , b[3], b[i]
使得 a数组是b数组的前缀和,b数组是a数组的差分
a[i] = b[1] + b[2] + …+ b[i]
我们要将一个数列a的[l, r]范围内加上(或减去)一个数c,可对a的差分数组b进行如下操作:
b[l] += c, b[r + 1] -= c;
本题利用差分,首先对于每一个计划,计算应在哪个时间段内做核酸使得该计划能成功通行,让该时间段上的通行数都加一。
设 q 时刻做核算;t,k , c
分别代表 t 时刻进入某场所,k 小时出核酸结果,场所需要持 c 小时以内的核酸证明。
- 因此能够通行需要满足的条件 : q + k < = t < = q + k + c − 1 q + k <= t <= q + k + c - 1 q+k<=t<=q+k+c−1 ;
- 通过不等式变形为 : t − k − c + 1 < = q < = t − k t - k - c + 1 <= q <= t - k t−k−c+1<=q<=t−k;
因此对于某个出行计划而言, q时刻做核酸只要满足 ② 式子即可通行。
- 所以我们需要开辟一个数组来记录每个时间能通行的数量,
- 当遍历完所有通行计划后,对差分数组进行还原成原始数组,
- 就可以利用数组下标直接得到询问的结果
- 需要定义一个数组res用于存储 i 时刻做核酸可以通过的计划数目。因为在出行计划输入时,即可根据 ②算出满足该计划出行的做核酸的范围[a,b];
- 再将res数组中下标范围从 [a,b] 进行 + 1;[a,b]+1 利用差分的方法,例如
[4, 9],只需要让res[4] + 1, res[10] - 1;
- 然后让res数组求前缀和 :
res[i] = res[i-1] + res[i] ;
- 接着对于输入的
q
只需返回res[q]
即可。
#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 200010;
int res[N];
int main()
int n, m ,k;
cin >> n >> m >> k;
for (int i = 0; i < n; i++)
int t, c;
cin >> t >> c;
// 在[l,r]时间段内做核酸,则t时刻可进入
int l = max(t-k-c+1, 0);
l = min(l, 200000);
int r = max(0, t-k);
r = min(r, 2000000);
// 在[l, r]时间段内能出行的次数+1
res[l] += 1;
res[r+1] -= 1;
//利用差分计算每个时间的能出行个数
for (int i = 1; i < 200001; i++)
res[i] += res[i-1]; // 累计求和
for (int i = 0; i < m; i++)
int q;
cin >> q;
cout << res[q] << endl;
return 0;
加油!
感谢!
努力!
以上是关于CCF-CSP 202203 赛题训练的主要内容,如果未能解决你的问题,请参考以下文章