Codeforces Round 802 (Div. 2)

1|0基本情况

A题秒了。

B题经典+4。

C题没想法(大概想了半小时)。

2|0B. Palindromic Numbers

Problem - B - Codeforces

2|1起步

首先很明显是高精。

然后要求加上的数字位数和给的位数相同。

答案不限制,只要回文就行。

第一思路就是口胡几个万能的回文答案。

  • 给定的数的第一位比 9

    • 显然,把每一位都覆上 9 可以完成这个情景。

    • for (int i = 0; i < a.len; i++) tb[i] = '9';
  • 给定的数的第一位就是 9

    • 明显要口胡一个多一位的回文数。

    • 然后一开始我就真纯口胡了。

      if (a.str()[0] == '9') { int bn = a.len + 1; if (bn & 1) { for (int i = 0; i < bn >> 1; i++) { tb[i] = cnt++; } for (int i = bn >> 1; i < bn; i++) { tb[i] = cnt--; } } else { for (int i = 0; i < bn >> 1; i++) { tb[i] = cnt++; } cnt--; for (int i = bn >> 1; i < bn; i++) { tb[i] = cnt--; } } }
    • 大概就是搞一个12321这类的回文串,然而这有可能是错的啊啊

2|2改错

幸好是发现了上面那个问题。

比如 n=18

那么我口胡的串就是 1234567891011...

你要不看看自己在说什么。。。

一位放两位了都开始。

所以为啥不找一个和 999 一样通用的呢

n=3 来分析:

考虑 a900 时,我们发现:

  • 只有当 a+b900<1000a+b 减去最小的 a 不能超过 n 位数)
  • a+b999100a+b 减去最大的 a 不能不到 n 位数)
  • 随便移个项就能得到 1099a+b<1900
  • 在这个范围里随便拎个回文数出来(比如 1111)就行了。

2|3代码

大整数类就不复制过来了,太长了。

#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; char tb[100010]; void solve() { int n; memset(tb, '\0', sizeof(tb)); Big_integer a = Big_integer(); cin >> n >> a; if (a.str()[0] == '9') for (int i = 0 ; i < a.len + 1; i++) tb[i] = '1'; else for (int i = 0; i < a.len; i++) tb[i] = '9'; Big_integer b = Big_integer(tb); cout << b - a << endl; } int main() { int _; std::cin >> _; while(_--) solve(); return 0; }

3|0C. Helping the Nature

Problem - C - Codeforces

要用差分,待我学学。


OK周一学成归来。

3|1思路

我们考虑我们是怎么使得整个序列的数都变成 0

  • 将序列中的所有数都变成同一个数,然后同时加或减某一个数之后才能做到。

  • 或者将序列的中间变成 0,将序列的左右部分分别变成同一个数,但是这样跟原问题有啥区别吗,还变得更加复杂了,所以就果断弃掉这个思路。

考虑如何操作使得区间中的所有数都变成同一个数:

我们考虑如果对原序列做差分,那么我们最终的答案就是差分序列所有的值为 0,序列中的所有的数是同一个数。

我们会发现一个很神奇的事情:我们对于一个前缀/后缀整体减一,只会对一个位置的差分值产生影响,加一或减一,那么就利用这个性质一点一点将差分数组变成 0 就可以了。

注意:这只是将整个序列都变成同一个数,还需要将所有的数都变成 0,这一步不能忘记了。

3|2代码

对于一个差分后的值 x,因为每一次操作都只能加一或减一,所以也就是 |x| 次操作后能变成 0。我的代码里维护的 h 值即差分序列全部变成 0 之后,原序列中的这个数(即原序列中所有都相同的每个数)是多少。

#include<iostream> #include<algorithm> const int N = 2e5 + 10; int a[N], n; long long b, ans; void solve() { ans = 0; std::cin >> n; for (int i = 1; i <= n; i++) { std::cin >> a[i]; } long long h = a[1]; for (int i = 2; i <= n; i++) { b = a[i - 1] - a[i]; ans += abs(b); if (b > 0) h -= b; } ans += abs(h); std::cout << ans << std::endl; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); int _; std::cin >> _; while(_--) solve(); return 0; }

然而这是错的!

调了半天发现是 abs 的问题。

我用的 abs 没有声明 std,所以是 C 自带的,而这个 C 自带的只能处理 intlong long 就会爆掉。

C++abs ,即加上 std::abs 就过了。

#include<iostream> #include<algorithm> const int N = 2e5 + 10; int a[N], n; long long b, ans; void solve() { ans = 0; std::cin >> n; for (int i = 1; i <= n; i++) { std::cin >> a[i]; } long long h = a[1]; for (int i = 2; i <= n; i++) { b = a[i - 1] - a[i]; ans += std::abs(b); if (b > 0) h -= b; } ans += std::abs(h); std::cout << ans << std::endl; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); int _; std::cin >> _; while(_--) solve(); return 0; }

__EOF__

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