Codeforces Round 814 (Div. 2)

1|0基本情况

又是过了ABC。

A、B思路更多的是从数据上分析出来的,过的很顺。

C经典拿评测机来调试,甚至还RE了一次,最后终于过了。

2|0C. Fighting Tournament

Problem - C - Codeforces

2|1第一次改错

这题我的思路是找到规律后,优先队列加二分查找。

但是一直WA第二个点,这是我一开始的代码:

void solve() { int n, Q, cnt = 0; std::cin >> n >> Q; int maxx = -1; for (int i = 1; i <= n; i++) std::cin >> a[i], maxx = std::max(maxx, a[i]); std::priority_queue<int,std::vector<int>,std::greater<int>> q; q.push(a[1]); for (int i = 2; i <= n; i++) { cnt++; q.push(a[i]); tag[q.top()].push_back(cnt); q.pop(); if (q.top() == maxx) break; } while(Q--) { int u, k; std::cin >> u >> k; if (k >= cnt) { if (a[u] == maxx) std::cout << tag[a[u]].size() + k - cnt + 1; else std::cout << tag[a[u]].size() ; } else { auto p = std::lower_bound(tag[a[u]].begin(), tag[a[u]].end(), k); std::cout << (p - tag[a[u]].begin()) + 1; } std::cout << std::endl; } }

可以说是漏洞满篇,第一次改错我发现了一下几个问题(可恶的是样例都没卡掉)

  • tag[a[u]].size() + k - cnt

    • 这个结果是可能爆 int
    • 前面加上 long long 强转
  • tag[q.top()].push_back(cnt);

    • 这个点是我造了一组数据才发现的,(样例到底怎么过的?)。

    • 经典胡言乱语,我这里开的是小优先的优先队列,明明队首是小的,而这里想要的是记录胜者的场次。

    • 语句调换一下,先 pop 再剩下的 top 就是最大的了。

    • q.push(a[i]); q.pop(); tag[q.top()].push_back(cnt);

然而提交后还是WA on test 2

2|2第二次改错

void solve() { int n, Q; std::cin >> n >> Q; long long cnt = 0; int maxx = -1; for (int i = 1; i <= n; i++) std::cin >> a[i], maxx = std::max(maxx, a[i]), tag[i].clear(); std::priority_queue<int,std::vector<int>,std::greater<int>> q; q.push(a[1]); for (int i = 2; i <= n; i++) { cnt++; q.push(a[i]); q.pop(); tag[q.top()].push_back(cnt); if (q.top() == maxx) break; } while(Q--) { int u, k; std::cin >> u >> k; if (k >= cnt) { if (a[u] == maxx) std::cout << (long long) tag[a[u]].size() + k - cnt; else std::cout << tag[a[u]].size() ; } else { auto p = std::lower_bound(tag[a[u]].begin(), tag[a[u]].end(), k); std::cout << (long long) (p - tag[a[u]].begin()) + 1; } std::cout << std::endl; } }

还是通过造数据找到的问题。

lower_bound 我下意识的认为是找第一个小于等于 k 的位置了,(什么根据题目自适应),但实际上是找第一个大于等于 k 的位置啊!所以整个 else 都是错的,再改。

else { auto p = std::lower_bound(tag[a[u]].begin(), tag[a[u]].end(), k); if (*p == k) std::cout << (long long) (p - tag[a[u]].begin()) + 1; else { if (p == tag[a[u]].begin()) std::cout << 0; else { p--; std::cout << (long long) (p - tag[a[u]].begin()) + 1; } } }

然后RE了。

2|3第三次改错

这个时候思路就比较清晰了,因为RE大概率就是迭代器操作的问题,然后我就发现要是没找到怎么办

比如我要查询的数据是第 7 轮,总共比了 9 轮,所以不会被上面那个 if 处理,而是转到了 else

然而查询的这个人最后赢得是第 5 轮,那么此时 lower_bound 是找不到第一个大于等于 7 的数的,它会返回 tag[a[u]].end()

其实到目前为止也没问题,因为我下面的算法已经让 p 自减了,算出来的正确性是可以保证的。

但是,我有一个语句是 if(*p == k) 而这里当 p = tag[a[u]].end() 的时候,显然会访问一个不确定的指针指向的值,这就导致了RE.

我是直接在这条语句上面加了特判来规避了RE,终于AC。

void solve() { int n, Q; std::cin >> n >> Q; long long cnt = 0; int maxx = -1; for (int i = 1; i <= n; i++) std::cin >> a[i], maxx = std::max(maxx, a[i]), tag[i].clear(); std::priority_queue<int,std::vector<int>,std::greater<int>> q; q.push(a[1]); for (int i = 2; i <= n; i++) { cnt++; q.push(a[i]); q.pop(); tag[q.top()].push_back(cnt); if (q.top() == maxx) break; } while(Q--) { long long u, k; std::cin >> u >> k; if (k >= cnt) { if (a[u] == maxx) std::cout << (long long) tag[a[u]].size() + k - cnt; else std::cout << tag[a[u]].size() ; } else { auto p = std::lower_bound(tag[a[u]].begin(), tag[a[u]].end(), k); if (p == tag[a[u]].end()) std::cout << tag[a[u]].size(); else if (*p == k) std::cout << (long long) (p - tag[a[u]].begin()) + 1; else { if (p == tag[a[u]].begin()) std::cout << 0; else { p--; std::cout << (long long) (p - tag[a[u]].begin()) + 1; } } } std::cout << std::endl; } }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17900877.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示