Codeforces Round 815 (Div. 2)

1|0基本情况

脑子太不清楚了。

A题有思路,但是各种细节问题(数论题太不熟练了),错了好几次才过。

B题直接分析数据愣猜一个解,猜对了。

2|0A. Burenka Plays with Fractions

Problem - A - Codeforces

难点在分析输出 1 的情况。

我的想法是通分,然后直接比分子是否互相整除,想法很对,但是实现一直犯病。

  • 本意是为了防止爆long long 所以先对两个分数约分一下,但是这样写代码,第一次 a 除完 gcd 之后,第二次求得 gcd(a,b) 明显就不是原来的了啊!。

    a /= gcd(a, b); b /= gcd(a, b); c /= gcd(c, d); d /= gcd(c, d);

    修改过后

    ll gcd_1 = gcd(a, b), gcd_2 = gcd(c, d); a /= gcd_1; b /= gcd_1; c /= gcd_2; d /= gcd_2;
  • 通分更是重量级

    a *= lcm(b, d); c *= lcm(b, d)

    经典胡言乱语,两个分子光乘分母的最小公倍数是在做什么?肯定要除去对应地分母啊。

    a *= lcm(b, d) / b; c *= lcm(b, d) / d;

终于AC。

void solve() { ll a, b, c, d; std::cin >> a >> b >> c >> d; if (a * d == b * c) {std::cout << 0 << std::endl; return ;} if (a == 0 || c == 0) {std::cout << 1 << std::endl; return ;} ll gcd_1 = gcd(a, b), gcd_2 = gcd(c, d); a /= gcd_1; b /= gcd_1; c /= gcd_2; d /= gcd_2; a *= lcm(b, d) / b; c *= lcm(b, d) / d; if (a % c == 0 || c % a == 0) {std::cout << 1 << std::endl; return ;} std::cout << 2 << std::endl; return ; }

3|0B. Interesting Sum

Problem - B - Codeforces

猜的解法,不会证明:

void solve() { int n; std::cin >> n; std::vector<int> a(n + 10); for (int i = 1; i <= n; i++) std::cin >> a[i]; std::sort(a.begin() + 1, a.begin() + n + 1); std::cout << a[n] + a[n - 1] - a[1] - a[2] << std::endl; }

证明如下:

思考正解,要让原式最大,就要让两个 max 得到的值最大,min 得到的值最小。

什么最大?什么最小?当然是最大、次大、最小、次小这四个值!

这时有人要问了:你怎么保证一定能把这四个值分成符合条件的两组呢?

干脆枚举,简洁明了。设最大、次大、最小、次小分别是 a,b,c,d

  • abcd,可以变成 a|bc|d
  • abdc,可以变成 a|bd|c
  • adbc,可以变成 |ad|bc

这说明了我们的猜想是正确的(实际上这就是分割一个环)。

就这样得到最优的 O(n) 做法,输出 a+bcd 即可。


__EOF__

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