问题描述
我在hackerearth尝试解决模强度问题,
https://www.hackerearth.com/practice/basic-programming/implementation/basics-of-implementation/practice-problems/golf/modulo-strength-4/,
所以基本上我们必须找到所有这样的对。 (比如 i,j)使得 A[i]%k=A[j]%k 其中 k 是一个否。在问题中给出,
我尝试了蛮力方法并在最后的一些测试用例中超出了时间限制,
在讨论选项卡中我发现了一个有效的代码,但我不明白到底是什么确实如此,以及所用算法背后的基本思想。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int n,k,s=0;
cin>>n>>k;
int a[n];
vector<int>v(k,0); // Specially this part,what does it store?
for(int i=0;i<n;i++)
{
cin>>a[i];
v[a[i]%k]++;
}
for(int i=0;i<k;i++)
{
s+=v[i]*(v[i]-1);
}
cout<<s;
}
这是代码,我想理解它,以便我可以将此逻辑应用于其他问题。
解决方法
让我们首先了解代码中每个变量的用途。
n,k,s
的目的是明确给出的。
a[n]
用于读取数组中的数字。
std::vector<int>v(k,0)
存储 k 大小的 0 向量,v[i]
表示 a[n]
中 a[j]%k==i
的变量数。
在最后一个循环中,完成了以下操作。可以用 n
元素构造的对数是 n*(n-1)
(基本组合),如果我们有满足条件的 v[i]
数和 a[j]%k==i
数可以构造的对数是 v[i]*(v[i]-1)
。循环对每个剩余 i
的对数求和。
有几个问题;
- "bits/stdc++.h" 不是标准头
- 变长数组,如
int a[n]
,是非标准的,容易出现运行时错误(这也是完全没有必要的) -
#define int long long
使代码具有未定义的行为。
这是一个固定版本,有一些小的重命名和澄清评论:
#include <iostream>
#include <vector>
int main() {
long long n,k;
cin >> n >> k;
// There are k groups of friends.
std::vector<int> friends(k);
// Count how many people there are in each group.
for(int i = 0; i < n; i++)
{
int x;
std::cin >> x;
friends[x%k]++;
}
long long sum = 0;
for(int i = 0; i < k; i++)
{
// In a group of N mutual friends,each person has N-1 friends.
sum += friends[i] * (friends[i]-1);
}
std::cout << sum;
}