CSPS2024题目总结
T1 决斗
签到题,考场上10min就做出来了。
我的方法是排序之后贪心打怪,就是用尽量小的怪去打现在场上最小的怪。用一个同侧双指针实现。 \(O(nlogn)\)。
另一种方法注意到了值域很小,可以放进桶里做到 \(O(n)\)。
还有一种方法。junjun大佬说答案就是出现次数最多的数的出现次数,感性理解一下也是对的。
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long;
const int N = 1e5 + 5;
int a[N], n;
signed main(){
// freopen("duel.in","r",stdin);
// freopen("duel.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n;
F(i, 1, n) cin >> a[i];
sort(a + 1, a + n + 1);
int nw = 1, ans = n;
F(i, 2, n){
if(a[i] > a[nw]) -- ans, ++ nw;
}
cout << ans << '\n';
return 0;
}
T2 超速检测
第一问:算出每辆车超速的临界位置 \(x\),看一下超速区间里面有没有检测仪,有的话答案 +1。
如果 \(a_i \lt 0\),那么超速区间为 \([d[i], x]\)
如果 \(a_i \ge0\),那么超速区间为 \([x, p[m]]\)。
这里涉及到非常多令人作呕的上下取整问题,下来调了一个多小时……
第二问:把第一问里面有效的超速区间拿出来,问题模型就是:
选最少的特殊点,使得每个区间都包含至少一个特殊点。
考场上想到了二分+贪心,但最终坚定地选择了线段树(嘻嘻嘻……还没写出来,我是sb)
考场做法疑似 \(60 \sim 80pts\),哎我都不奢求什么了,希望 \(60\) 分保底顺利拿到……(考场上真是紧张坏了)
正解就是先给区间排序(以 \(l\) 为第一关键字,\(r\) 为第二关键字)然后贪心,由于 \(l\) 已经保证递增了,所以贪心的功夫全在 \(r\) 怎么处理上。
记 \(pmin\) 表示最新选择的点。发现一个性质:\(pmin\) 一定是尽量靠右的一个位置,因为这样的话,随着 \(l\) 增加, \(pmin\) 能被尽量多的区间包含。
只要 \(l_i \le pmin\),\(pmin\) 就可以一直产生贡献,并且如果 \(r_i \lt pmin\),为了实际上真的把 \(i\) 区间装进来了,要将 \(pmin\) 更新为 \(r_i\)。
当 \(l_i \gt pmin\),我们就新开一个点,初始位置 \(pmin = r_i\)。
画两个图玩一下,发现很对。(嘻嘻……
思路就是这样。
自己感觉难点一方面是要往简单想,既然一开始有贪心的想法,为什么不先试着多玩两个图甚至码一下呢?
另一方面就是第一问细节是真多,要套公式,同时还要注意上下取整的问题。(如果写 \(nlogn\) 好像码起来会稍微容易一点)
值域较小,可以做到 \(O(Tn)\)。(其实我还是排了个序)
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long;
char buf[100], *p1 = buf, *p2 = buf;
inline int gc(){
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
int x = 0; char ch; bool f = 1;
while(!isdigit(ch = gc())) f ^= (ch == '-');
do x = (x << 3) + (x << 1) + (ch ^ 48); while(isdigit(ch = gc()));
return f ? x : -x;
}
const int N = 1e5 + 5;
struct cat{
int l, r;
bool operator < (const cat &other)const{
return l == other.l ? r < other.r : l < other.l;
}
}e[N];
int T, n, m, L, o, cnt = 0;
int d[N], v[N], a[N], p[N];
int pos[1000006], s[1000006];
void init(){
n = rd(), m = rd(), L = rd(), v[0] = rd();
F(i, 1, n) d[i] = rd(), v[i] = rd(), a[i] = rd();
F(i, 1, m) p[i] = rd(), pos[p[i]] = i, s[p[i]] ++ ;
}
int tot = 0;
int solve1(){
int st = 1, ans1 = 0;
F(i, 1, L){
if(pos[i]){
F(j, st, i) pos[j] = pos[i];
st = i + 1;
}
s[i] += s[i - 1];
}
G(i, L, 1){
if(pos[i]) break;
pos[i] = m + 1;
}
F(i, 1, n){
ll x;
if(a[i] == 0){
if(v[i] <= v[0]) continue;
if(s[L] - s[d[i] - 1]){
e[++ cnt] = (cat){pos[d[i]], m};
++ ans1;
}
continue;
}
x = (1ll * v[0] * v[0] - 1ll * v[i] * v[i]) / (2ll * a[i]) + d[i];
if(a[i] > 0){
if(v[0] < v[i]){
if(s[L] - s[d[i] - 1]){
e[++ cnt] = (cat){pos[d[i]], m};
++ ans1;
}
}
else{
++ x; // begin to over
if(x > L) continue;
if(s[L] - s[x - 1]){
e[++ cnt] = (cat){pos[x], m};
++ ans1;
}
}
}
else{
if(v[i] <= v[0]) continue;
if((1ll * v[0] * v[0] - 1ll * v[i] * v[i]) % (2ll * a[i]) == 0) -- x; // end to over
if(x < d[i]) continue;
int l = pos[d[i]], r = pos[x + 1] - 1;
if(x >= L) x = L, r = m;
if(s[x] - s[d[i] - 1]){
e[++ cnt] = (cat){l, r};
++ ans1;
}
}
}
return ans1;
}
int solve2(){
sort(e + 1, e + cnt + 1);
int pmin = 0, ans2 = 0;
F(i, 1, cnt){
int l = e[i].l, r = e[i].r;
if(l > pmin){
++ ans2;
pmin = r;
}
else pmin = min(pmin, r);
}
return m - ans2;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
T = rd();
while(T --){
init();
int ret1 = solve1(), ret2 = solve2();
printf("%d %d\n", ret1, ret2);
F(i, 0, L) pos[i] = s[i] = 0;
cnt = 0;
}
return 0;
}
T3 染色
\(O(n^2)\)
先考虑 \(O(n^2)\) 做法,记 \(f[i][1/0]\) 表示 \(i\) 的颜色和 \(i - 1\) 一样 / 不一样 的最大得分。
对于颜色一样,有:
\]
对于颜色不一样,我们需要在 \(1 \sim i - 1\) 中找一个位置 \(j\) 和 \(i\) 染成同种颜色,并且它们之间全是异色,形如:
\]
思考一下,会发现现在最大的问题是 \(j + 1\) 位置会和哪个位置匹配。转移可大致写为:
\]
问号就是 \(j + 1\) 的贡献。难道为了这个地方我们又要多枚举一重循环?
这里有一个很逆天的 \(trick\),我们可以从 \(f[j + 1][0]\) 转移过来!
解释一下:回到定义,我们只规定颜色一不一样,没说到底谁0谁1,所以 \(f[j + 1][0]\) 就不用再考虑 \(j + 1\) 的贡献了,前面已经求出来了。
新的转移为:
\]
\(val\) 可以前缀和预处理,于是就有了一个 \(O(n^2)\) 做法。
拆式子
加上前缀和后,式子可以写成:
\]
对于 \(\max\) 里面可以直接前缀最大值,记作 \(maxn\)。
对于 \(a[i]/0\),记 \(mx[a[i]]\) 表示
\]
所以 \(f[i][0] = \max(maxn, mx[a[i]] + s[i - 1])\)。
时间复杂度 \(O(Tn)\)。
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using std::max;
using ll = long long;
char buf[100], *p1 = buf, *p2 = buf;
inline int gc(){ return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++; }
inline int rd(){
int x = 0; char ch;
while(!isdigit(ch = gc()));
do x = (x << 3) + (x << 1) + (ch ^ 48); while(isdigit(ch = gc()));
return x;
}
const int N = 2e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll f[N][2], s[N], mx[1000006];
int n, T, a[N];
void init(){
n = rd(); int amax = 0;
F(i, 1, n) a[i] = rd(), amax = max(amax, a[i]);
F(i, 0, n) f[i][0] = f[i][1] = 0;
F(i, 0, amax) mx[i] = -inf;
s[0] = s[1] = 0; F(i, 2, n) s[i] = s[i - 1] + ((a[i] == a[i - 1]) ? a[i] : 0);
}
ll solve(){
ll maxn = 0;
F(i, 1, n){
f[i][1] = max(f[i - 1][1], f[i - 1][0]) + ((a[i] == a[i - 1]) ? a[i] : 0);
f[i][0] = s[i - 1] + maxn;
if(mx[a[i]] != -inf) f[i][0] = max(f[i][0], s[i - 1] + mx[a[i]]);
mx[a[i - 1]] = max(mx[a[i - 1]], f[i][0] - s[i] + a[i - 1]);
maxn = max(maxn, f[i][0] - s[i]);
} return max(f[n][0], f[n][1]);
}
signed main(){
T = rd(); while(T --) init(), printf("%lld\n", solve());
return fflush(0), fclose(stdin), fclose(stdout), 0;
}
总结
这次比赛让我意识到了 “策略” 和 “思维变现” 的重要性。
关于策略,错误地沿用了一贯打模拟赛时的策略,在 T1 切掉后没有选择先把题都读一遍然后找好拿的分先拿,而是选择硬刚 T2,打到 16:30 还是一分未拿直接慌了,4h 赛制和 4.5h 的实际感受完全不一样!
如果让我再决策一次,我会先通读题目,然后把 T2 60pts,T3 20 ~ 35pts 先写了(不是写完就至少180谁不心动?)然后我可能会开 T2 正解,也可能开 T3 50分,不好还原当时的心境……但这个时候再写 T2 也会淡定许多吧?T4那个暴力嘛,看最后时间够不够了。
关于思维变现,昨晚已和 lyy 深入交流过了(别人是物竞啊%%%)这次 T2 想过二分+贪心然后否了选择了线段树,写线段树又一直再自我怀疑;T3 一眼 dp 但慌乱之中没有心情也没有时间深入想下去。
我觉得有两点反思。
第一,肯定自己,思维肯定不差!这两天 “采访了” 机房很多同学,他们想到了的点,我也都想到了类似的。“伸脖子是一刀,缩脖子也是一刀”,要自信!
第二,矫正自己,现在最大的问题是 思维很活跃 但 变现到成绩上很少!要刷真题,刷好题,不断地去摸索什么难度的题一般 不会想什么,应该先想什么,哪些点子一定是不该出现在这个位置的题……只要你找到那条思维的主线,你的noip一定可以1=!
“新旧之间没有怨讼,唯有真与伪是大敌。”——柴静
CSPS2024题目总结的更多相关文章
- 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 一道返回num值的小题目
题目描述: 实现fizzBuzz函数,参数num与返回值的关系如下: .如果num能同时被3和5整除,返回字符串fizzbuzz .如果num能被3整除,返回字符串fizz .如果num能被5整除,返 ...
- 谈谈一些有趣的CSS题目(一)-- 左边竖条的实现方法
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(五)-- 单行居中,两行居左,超过两行省略
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(六)-- 全兼容的多列均匀布局问题
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 谈谈一些有趣的CSS题目(七)-- 消失的边界线问题
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
随机推荐
- sqlserver 索引优化 CPU占用过高 执行分析 服务器检查[转]
SELECT TOP 10 [Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) ...
- SMU 2024 spring 天梯赛4
SMU 2024 spring 天梯赛4 7-1 心理阴影面积 - SMU 2024 spring 天梯赛4 (pintia.cn) 由 \(d = \frac{Ax+By+c}{\sqrt {A^2 ...
- Flex相册
有一个项目用到了Flex,于是抽时间用flex与java做了一个相册,并且添加了上传功能,不过暂时没有针对具体的用户进行存储.下面是图片:
- 快手 内推码:TYORVzmsw 秋招 应届生/实习生 真正本人内推 已有多人在我内推之后,接连顺利通过了HR筛选、用人部门筛选、面试!
内推码:TYORVzmsw 校园招聘岗位列表:https://campus.kuaishou.cn/#/campus/jobs?code=TYORVzmsw 真正的本人内部推荐! 已有多人在我内推之后 ...
- 讲讲Java的序列化反序列化?
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. 什么时候会用到 当只在本地 JVM 里运行下 Java 实例,这个时候是不需要什么序列化 ...
- MyBatis分页实现
目录 分页实现 limit实现分页 RowBounds分页 分页实现 limit实现分页 为什么需要分页? 在学习mybatis等持久层框架的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进 ...
- docker image 变小的办法
https://www.docker.com/blog/intro-guide-to-dockerfile-best-practices/ https://medium.com/sciforce/st ...
- 坑人的opencv安装
我想捡起来C++,最近在看opencv,于是我想着一起吧. 但是我低估了这个小麻烦的魅力,曾经安装opencv c++版本就头秃,如今依然头秃.说明我没长进啊-- 折腾了两天,终于装上了. 其中最麻烦 ...
- 个头小却很能“打”!合合信息扫描全能王推出A4便携式打印机
个头小却很能"打"!合合信息扫描全能王推出A4便携式打印机 过去,为了打印一份清晰工整的材料,人们往往需要到专门的打印店或办公室.处理文件.对于销售.物流人员.工程师.医生.媒 ...
- PTA甲级—树
1.树的遍历 1004 Counting Leaves (30分) 基本的数据结构--树,复习了链式前向星,bfs遍历判断即可 #include <cstdio> #include < ...