原题:2024牛客寒假算法基础集训营3 M题
方法一:
用递归进行长整数除法,暴力寻找,但是会超时
#include <bits/stdc++.h>
using namespace std;
bool f(string &s, int ans,int count) {
if (count > s.size()) {
if (ans % 36 == 0)return true;
return false;
}
bool b = false;
ans = ans * 10 + (s[count - 1] - '0');
if (ans < 36) b = f(s, ans, count + 1);
else {
ans = ans % 36;
b = f(s, ans, count + 1);
}
return b;
}
int main() {
int n;
cin >> n;
vector<long long>v(n, 0);
for (int i = 0; i < n; i++)cin >> v[i];
long long ans = 0;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
string temp1 = to_string(v[i]) + to_string(v[j]);
string temp2 = to_string(v[j]) + to_string(v[i]);
if ((temp1[temp1.size() - 1] - '0') % 2 == 0) {
if (f(temp1, 0, 1))ans++;
}
if ((temp2[temp2.size() - 1] - '0') % 2 == 0) {
if (f(temp2, 0, 1))ans++;
}
}
}
cout << ans << "\n";
}
方法二:
用余数解决。因为设x,当x>=2时,10^x % 36恒等于28,所以当两个整数 p , q 拼接后,假如整数 q 位数大于等于两位,其余数为 ((p%36)*28 + q)%36。
可以举个例子:假如两个数为15, 105,拼接后为15105,15105%36=21
15105=15*1000+105
(15*1000+105)%36=[(15%36*1000%36)+105]%36=21
核心代码:
// v存放输入的正整数
void f(vector<ll>& v) {
// 记录每个数据对36取模的值
vector<ll>yushu(36, 0);
for (int i = 0; i < v.size(); i++) {
for (int j = 0; j < 36; j++) {
// 把余数j对应的整数拼接到v[i]前面
// 当v[i]<10时,10%36自然只能为10
if ((j * (v[i] < 10 ? 10 : 28) + v[i]) % 36 == 0) {
//若为0,说明找到余数,有几个数%36=j,ans就加几
ans += yushu[j];
}
}
//把当前的数%36后存入yushu中,防止把一个数用两次
//同时也可看出这里没有计算它们反过来拼接的情况,所以后面要反转数组v
如输入数据为6,3,这里只计算了63,没有算36
yushu[v[i] % 36]++;
}
}
完整代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n;
ll ans = 0;
void f(vector<ll>& v) {
vector<ll>yushu(36, 0);
for (int i = 0; i < v.size(); i++) {
for (int j = 0; j < 36; j++) {
if ((j * (v[i] < 10 ? 10 : 28) + v[i]) % 36 == 0) {
ans += yushu[j];
}
}
yushu[v[i] % 36]++;
}
}
int main() {
cin >> n;
vector<ll>v(n, 0);
for (int i = 0; i < n; i++)cin >> v[i];
//这里没有计算它们反过来拼接的情况,所以后面要reverse数组v
//如输入数据为6,3,这里只计算了63,没有算36
f(v);
//反转数组
reverse(v.begin(), v.end());
f(v);
cout << ans << "\n";
}