做题小结1.23-1.26
https://codeforces.com/contest/1904/problem/B


这题目意思有点逆天 意思是说你可以设置你的初试分数为ai 然后大鱼吃小鱼 输出你设置为ai时吃到的最多
鱼数量 每个i都要输出
然后这是一个双指针的题目 也是一个二分的题目 考察基本功
我个人认为我现阶段就是基础不牢 所以对于这种橙题 我是很喜欢补的很透彻的 橙怎么了
场上卡你的还管什么颜色
先介绍双指针写法
结构体排序就不说了
很显然还是经典写法 卡住一边让r跑的写法 这个一边就是指我们for循环卡住i
for (int i = 1; i <= n; i++) {
if (r>i) {
ans[a[i].index] = r - 1;
continue;
}
if(r!=i)
tot += a[i].num;
r=i;
while (tot >= a[r + 1].num&&r<n) {
tot += a[r + 1].num;
r++;
}
ans[a[i].index] = r -1;
}
二分怎么写
这题双指针好写 但是二分不好写
我们先思考下 我们对于一个数需要清楚他吃了多少鱼(以他目前实力都能吃的)
然后吃完了后我们有一个前缀和 然后我们再看 这个前缀和他能延申到哪里呢?
很明显 我们可以预处理 当前缀和小于某个i时候是可以预处理的
我觉得可以这样预处理
for (int i = n - 1; i >= 1; i--) {
if (a[i + 1].num > pre[i]) {
cnt[i] = i;
} else cnt[i] = cnt[i + 1];
}
for (int i = 1; i <= n; i++) {
//也可以再node w={a[i},0};
int w = upper_bound(a + 1, a + 1 + n, a[i],cmp) - a;
ans[a[i].index]=cnt[w-1]-1;
}
https://codeforces.com/contest/1903/problem/C

这个题 我二次做只能想到要倒着做了 但是还是想不清楚怎么分段
又看了代码 才知道是一个dp 还记得第一次做这个题的心情 这个题 这个怎么分块
其实不重要 我们把它理解为再加一次后缀和就行 于是这个题的状态转移就出来了
i:n->1
dp[i]max(dp[i+1]+a[i],dp[i+1]+sum+a[i])
sum+=a[i];
很好的一题
https://codeforces.com/contest/1904/problem/C

重新看这个题 一下子就想起来了 所以就秒了 不过这个题还是很有价值的 就是
k=2的放置 我们二分一个最接近的数字 假设Ai 二分出来了Ak 那么我们二分用的lowerbound默认>=
还有可能Ak-1也是很接近的 所以这是一个很容易漏的点 我翻了好几次这种毛病了
切记!
https://codeforces.com/contest/1904/problem/A

重新做还是一愣一愣的 看了代码才知道咋写
没错 set还可以放pair!!!!很好的一道题
set<pair<int, int>>s1;
set<pair<int, int>>s2;
//学到了 set可以放pair
for (int i = 0; i <= 3; i++) {
s1.insert({x + a*dx[i], y + b*dy[i]});
s1.insert({x + b*dx[i], y + a*dy[i]});
s2.insert({x2 + a*dx[i], y2 + b*dy[i]});
s2.insert({x2 + b*dx[i], y2 + a*dy[i]});
}
https://codeforces.com/contest/1900/problem/B

重做还是没做出来哇 讲下思路 这题很有趣
如果留1势必要2 3 做操作 那么 如果2 3 的数量是 这样的 2 4 那么我们可以 变成0 2
然后 此时a和c做操作产生b b再和c操作 这种的操作是消耗2个c 第一种操作是各消耗b c一个
你就会发现如果数量之和是偶数那么肯定可以只留下a一个球 所以此题就ok了

https://codeforces.com/contest/1900/problem/A
这题当时给我做傻了 重新做印象比较深刻 就做出来了 其实就是个诈骗 i-1 i+1 产生的i可以源源不断使用
拿这个题是想讲下这个string find未找到 string::npos
string w="...";
if(s.find(w)!=string::npos){
cout<<2<<endl;return ;
}

浙公网安备 33010602011771号