C++ 改进嵌套循环的优化

C++ 改进嵌套循环的优化,c++,nested-loops,C++,Nested Loops,我正在制作一个简单的程序来计算一个数组中可以被3个数组长度整除的对的数量,值由用户决定 现在我的代码非常好。但是,我只想检查是否有一种更快的方法来计算它,从而减少编译时间 由于数组的长度为10^4或更少,编译器所用的时间少于100ms。然而,当它达到10^5时,峰值会达到1000毫秒,这是为什么呢?如何提高速度 #include <iostream> using namespace std; int main() { int N, i, b; b = 0;

我正在制作一个简单的程序来计算一个数组中可以被3个数组长度整除的对的数量,值由用户决定

现在我的代码非常好。但是,我只想检查是否有一种更快的方法来计算它,从而减少编译时间

由于数组的长度为10^4或更少,编译器所用的时间少于100ms。然而,当它达到10^5时,峰值会达到1000毫秒,这是为什么呢?如何提高速度

#include <iostream>

using namespace std;

int main()
{
    int N, i, b;
    b = 0;
    cin >> N;

    unsigned int j = 0;
    std::vector<unsigned int> a(N);
    for (j = 0; j < N; j++) {
        cin >> a[j];
        if (j == 0) {
        }

        else {
            for (i = j - 1; i >= 0; i = i - 1) {
                if ((a[j] + a[i]) % 3 == 0) {
                    b++;
                }
            }
        }
    }

    cout << b;

    return 0;
}
#包括
使用名称空间std;
int main()
{
int N,i,b;
b=0;
cin>>N;
无符号整数j=0;
std::载体a(N);
对于(j=0;j>a[j];
如果(j==0){
}
否则{
对于(i=j-1;i>=0;i=i-1){
如果((a[j]+a[i])%3==0){
b++;
}
}
}
}
cout您的算法具有
O(N^2)
复杂性。有一种更快的方法

(a[i] + a[j]) % 3 == ((a[i] % 3) + (a[j] % 3)) % 3
因此,您不需要知道确切的数字,只需要知道它们被三除后的余数。两个余数为零的数字
(0+0)
和两个余数
1
2
(1+2)
可以接收到和的余数

结果将等于
r[1]*r[2]+r[0]*(r[0]-1)/2
,其中
r[i]
是余数等于
i
的数字数量

int r[3] = {};
for (int i : a) {
    r[i % 3]++; 
}
std::cout << r[1]*r[2] + (r[0]*(r[0]-1)) / 2;
intr[3]={};
对于(int i:a){
r[i%3]++;
}

std::cout我以前遇到过这个问题,虽然我没有找到我的特定解决方案,但您可以通过散列来改进运行时间

代码如下所示:

<代码> //C++程序检查ARR(0…N-1)是否可以划分 //成对的,使得每一对都能被k整除。 #包括 使用名称空间std; //如果arr[0..n-1]可以分成对,则返回true //和可以被k整除。 布尔canPairs(整数arr[],整数n,整数k) { //奇数长度数组不能分成对 如果(n&1) 返回false; //创建一个频率数组以计数出现次数 //被k除后的所有余数。 地图频率; //计算所有余数的出现次数 对于(int i=0;iCAN对(arr、n、k)如果你的代码工作正常,你只想改进它,考虑一下问。边注释。如果你优化了代码,你可能会改进“执行时间”。编译时间通常不是一个因素,因为在构建程序时只有一次发生这样的情况:考虑使用不同的编译器和不同的标志。l优化代码。@Renato:不要在代码中添加
goto
// A C++ program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
#include <bits/stdc++.h>
using namespace std;

// Returns true if arr[0..n-1] can be divided into pairs
// with sum divisible by k.
bool canPairs(int arr[], int n, int k)
{
    // An odd length array cannot be divided into pairs
    if (n & 1)
         return false;

    // Create a frequency array to count occurrences
    // of all remainders when divided by k.
    map<int, int> freq;

    // Count occurrences of all remainders
    for (int i = 0; i < n; i++)
        freq[arr[i] % k]++;

    // Traverse input array and use freq[] to decide
    // if given array can be divided in pairs
    for (int i = 0; i < n; i++)
    {
        // Remainder of current element
        int rem = arr[i] % k;

        // If remainder with current element divides
        // k into two halves.
        if  (2*rem == k)
        {
            // Then there must be even occurrences of
            // such remainder
            if (freq[rem] % 2 != 0)
                return false;
        }

        // If remainder is 0, then there must be two 
        // elements with 0 remainder
        else if (rem == 0)
        {
           if (freq[rem] & 1)           
               return false;
        }        

        // Else number of occurrences of remainder
        // must be equal to number of occurrences of
        // k - remainder
        else if (freq[rem] != freq[k - rem])
            return false;
    }
    return true;
}

/* Driver program to test above function */
int main()
{
    int arr[] =  {92, 75, 65, 48, 45, 35};
    int k = 10;
    int n = sizeof(arr)/sizeof(arr[0]);
    canPairs(arr, n, k)? cout << "True": cout << "False";
    return 0;
}