第十四节 数论 - 1
AT_arc149_a 题解
本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。
题目简述
求满足以下条件的小于 \(10 ^ n\) 数最大是多少?
-
每一位数字均相同;
-
是 \(m\) 的倍数。
数据范围:\(1\le n\le 10^5\),\(1\le m\le 10^9\)。
思路
首先每位数字都相同很好满足,仅需枚举 \(n\) 位后,枚举每位的数字 \(1 \sim 9\),注意不包含 \(0\),因为最高位不能为 \(0\)。
接着想要满足是 \(m\) 的倍数,可以想到类似动态转移的思路,定义二维数组 \(mp[i][j]\) 表示在有 \(i\) 位数的情况下每位都为 \(j\) 的数除以 \(M\) 的余数。在枚举中实时更新答案,因为位数是从 \(1 \sim N\),每位是从 \(1 \sim 9\),所以存储的答案一定为最大的解。
代码实现
经过以上分析及一些数组设计,很容易即可得到代码。首先我们先看一下 \(mp\) 数组的处理:
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= 9; j ++) {
mp[i][j] = (mp[i - 1][j] * 10 + j) % m;
if(!mp[i][j]) ans1 = i, ans2 = j;
}
可以看到第三行对于 \(mp\) 数组状态的转移:
可以从 \(i-1\) 位都是 \(j\) 的余数转移过来,根据同余的相关知识很容易推出转移方程式:
解决状态转移后需更新答案,这一部分很简单就不在赘述。接着需要在处理 \(mp\) 数组后,特判 \(-1\) 的情况:
if(!ans1 || !ans2) {
cout << "-1\n";
return 0;
}
这样整体代码框架就完成了。
AC code
#include<iostream>
using namespace std;
long long n, m, mp[100005][15];
long long ans1, ans2;
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= 9; j ++) {
mp[i][j] = (mp[i - 1][j] * 10 + j) % m;
if(!mp[i][j]) ans1 = i, ans2 = j;
}
if(!ans1 || !ans2) {
cout << "-1\n";
return 0;
}
for(int i = 1; i <= ans1; i ++) cout << ans2;
return 0;
}
A. 优美子数列
题目描述
数学家小 \(Q\) 得到了一个长度为 \(n\) 的数列 {\(a_n\)}。
小 \(Q\) 的幸运数字是 \(k\),所以他认为,若一个子数列 \(a_l\), \(a_l + 1\), …, \(a_r\) 的和为 \(k\) 的倍数,则该子数列是优美子数列。
小 \(Q\) 现在想考考你,{\(a_n\)} 里有多少个优美子数列呢?
输入格式
第一行输入两个正整数 \(n,k\)。
接下来一行输入 \(n\) 个数,代表 \(a_1\) 到 \(a_n\)。
输出格式
输出一行一个正整数,表示优美子数列的个数。
样例输入
5 3
1 2 3 4 5
样例输出
7
数据规模
对于 \(60\%\) 的数据,\(n \le 1000\);
对于 \(100\%\) 的数据,\(1 \le n \le 2 \times 10^5\),\(1 \le k \le 10^7\),\(-10^9 \le a_i \le 10^9\)。
点击查看代码
#include<iostream>
#include<map>
using namespace std;
long long n, k, a[200005];
long long ans = 0;
map<long long, long long> mp;
int main() {
cin >> n >> k;
mp[0] ++;
for(int i = 1; i <= n; i ++) {
int x;
cin >> x;
x %= k;
a[i] = ((a[i - 1] + x) % k + k) % k; // 防止负数
ans += mp[a[i]];
mp[a[i]] ++;
}
cout << ans << endl;
return 0;
}
编译结果
compiled successfully
time: 309ms, memory: 11632kb, score: 100, status: Accepted
> test 1: time: 0ms, memory: 3492kb, points: 10, status: Accepted
> test 2: time: 0ms, memory: 3384kb, points: 10, status: Accepted
> test 3: time: 1ms, memory: 3408kb, points: 10, status: Accepted
> test 4: time: 0ms, memory: 3360kb, points: 10, status: Accepted
> test 5: time: 1ms, memory: 3376kb, points: 10, status: Accepted
> test 6: time: 0ms, memory: 3464kb, points: 10, status: Accepted
> test 7: time: 14ms, memory: 4752kb, points: 10, status: Accepted
> test 8: time: 174ms, memory: 11632kb, points: 10, status: Accepted
> test 9: time: 49ms, memory: 7076kb, points: 10, status: Accepted
> test 10: time: 70ms, memory: 4912kb, points: 10, status: Accepted
本文来自博客园,作者:So_noSlack,转载请注明原文链接:https://www.cnblogs.com/So-noSlack/p/17578866.html