NC14380 位数差
题目
题目描述
给一个数组 ,定义 为在十进制下 与 的位数差,求 , 的位数为 。
输入描述
第一行读入一个正整数 。第二行读入 个非负整数,第 个表示 。
输出描述
一行表示答案。
示例1
输入
10 0 1 2 3 4 5 6 7 8 9
输出
20
题解
知识点:二分,数学。
我们用 表示 的十进制位数,则有:
其中, 可以在输入时候处理完。
而 与 和 顺序可以互换,因此该式与序列的排列顺序无关。所以从小到大排序,对每一个数查找某一结果的区间,由于选择比 小的数与 配对答案只可能是 和 而选择大的数会出现 到 ,而选择一种即可结果是相同的,我们选择前者查找答案 分界点,非常方便。显然只要查找大于等于 的第一个数 ,即第一个 结果为 的数即可。随后因为这个区间的所有数的位数至少是 ,因此加上 ,再加上位数多一的个数 ,于是对于这个数与小于他的数的配对总和就是 ,对每个数如此操作即可。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[100007]; int p[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000 }; int bit(int n) { if (!n) return 1; int ans = 0; while (n) n /= 10, ans++; return ans; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; ll ans = 0; for (int i = 1;i <= n;i++) cin >> a[i], ans -= (n - i) * bit(a[i]); sort(a + 1, a + n + 1); for (int i = 1;i <= n;i++) { int pos = lower_bound(a + 1, a + i, p[bit(a[i])] - a[i]) - a; ans += (i - 1) * bit(a[i]) + (i - pos); } cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16419369.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧