模强度,需要在用于计算答案的算法中进行解释

问题描述

我在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;
}