AcWing寒假每日一题2024
好久没刷算法了,记录活动中一些印象深刻的题目。
1.[AcWing4662.因数平方和]
题目描述
记
例如:
定义
给定
输入格式
输入一行包含一个正整数
输出格式
输出一个整数表示答案
数据范围
对于
对于
对于所有评测用例,
输入样例
100000
输出样例
680584257
解题思路
首先最简单的思路,针对每一个数,通过试除法获取其因数,求和,但是这样复杂度过高。
换个思路,针对每个数,其会对倍数在计算
当
1 2 3 4 5 6 7 8 9 10 11 12
12 6 4 3 2 2 1 1 1 1 1 1
可以看到,
对于
C++代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD = 1e9 + 7;
int n;
LL cal(int n) {
return n * (__int128)(n + 1) * (2 * n + 1) / 6 % MOD;
}
int main() {
cin >> n;
int res = 0;
for (int i = 1; i <= n; ) {
int x = n / i, y = n / x;
res = (res + (cal(y) - cal(i - 1)) * x) % MOD;
i = y + 1;
}
cout << (res + MOD) % MOD;
return 0;
}
2.[AcWing2875.超级胶水]
题目描述
小明有
他准备用胶水将这些石子粘在一起。
每颗石子有自己的重量,如果将两颗石子粘在一起,将合并成一颗新的石子,重量是这两颗石子的重量之和。
为了保证石子粘贴牢固,粘贴两颗石子所需要的胶水与两颗石子的重量乘积成正比,本题不考虑物理单位,认为所需要的胶水在数值上等于两颗石子重量的乘积。
每次合并,小明只能合并位置相邻的两颗石子,并将合并出的新石子放在原来的位置。
现在,小明想用最少的胶水将所有石子粘在一起,请帮助小明计算最少需要多少胶水。
输入格式
输入的第一行包含一个整数
第二行包含
输出格式
一个整数表示答案。
数据范围
输入样例1
3
3 4 5
输出样例1
47
输入样例2
8
1 5 2 6 3 7 4 8
输出样例2
546
解题思路
最开始的思路是贪心,每次取最小的两个粘在一起,借助堆。
假设
C++代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef long long LL;
int n, w[N];
priority_queue<int, vector<int>, greater<int>> q;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
LL ans = 0, sum = 0;
/*
for (int i = 1; i <= n; i++) q.push(w[i]);
while (q.size() > 1) {
int a = q.top(); q.pop();
int b = q.top(); q.pop();
ans += ((LL) a * b);
q.push(a + b);
}
*/
for (int i = 1; i <= n; i++) {
ans += sum * w[i];
sum += w[i];
}
printf("%lld", ans);
return 0;
}
3.[AcWing4646.爬树的甲壳虫]
题目描述
有一只甲壳虫想要爬上一棵高度为
输入格式
输入第一行包含一个整数
接下来
输出格式
输出一行包含一个整数表示答案,答案是一个有理数,请输出答案对质数
其中有理数
数据范围
对于
对于
对于所有评测用例,
输入样例1
1
1 2
输出样例1
2
输入样例2
3
1 2
3 5
7 11
输出样例2
623902744
解题思路
C++代码
#include <bits/stdc++.h>
using namespace std;
const int P = 998244353;
typedef long long LL;
int n;
LL qmi(int a, int b) {
LL res = 1;
while (b) {
if (b & 1)
res = res * a % P;
a = (LL) a * a % P;
b >>=1;
}
return res;
}
int main() {
scanf("%d", &n);
LL res = 0;
while (n--) {
int x, y;
scanf("%d%d", &x, &y);
res = (res + 1ll) * y % P * qmi(y - x, P - 2) % P;
}
printf("%lld\n", res);
return 0;
}
4.[AcWing5408.保险箱]
题目描述
小蓝有一个保险箱,保险箱上共有
小蓝可以任意调整保险箱上的每个数字,每一次操作可以将其中一位增加
当某位原本为
例如:
保险箱上一开始有一个数字
输入格式
输入的第一行包含一个整数
第二行包含一个
第三行包含一个
输出格式
输出一行包含一个整数表示答案。
数据范围
对于
对于
对于所有评测用例,
输入样例
5
12349
54321
输出样例
11
解题思路
首先,这里的操作可以看作是十进制加减法。操作时有如下性质
- 操作顺序不会影响操作结果
- 对于某一位操作时,不会影响右边数位的结果
- 对于某一位操作时往前一位最多进一位或者借一位
在最优解中,每一位操作次数区间为
,否则会产生进借位,不如直接操作被进或者借位
C++代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
string a, b;
int f[N][3];
int main() {
cin >> n >> a >> b;
memset(f, 0x3f, sizeof f);
f[n][1] = 0;
for (int i = n - 1; i >= 0; i--)
for (int j = 0; j < 3; j++)
for (int k = -9; k <= 9; k++)
for (int t = 0; t < 3; t++)
if (a[i] + k + t - 1 - b[i] == (j - 1) * 10)
f[i][j] = min(f[i][j], f[i + 1][t] + abs(k));
printf("%d\n", min({f[0][0], f[0][1], f[0][2]}));
return 0;
}
本文来自博客园,作者:Cocoicobird,转载请注明原文链接:https://www.cnblogs.com/Cocoicobird/p/18000364
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2023-02-21 2023.2.21AcWing蓝桥杯集训·每日一题