Devansh Kumar
Devansh Kumar

Reputation: 21

How do I reduce the running time of my program?

I was solving a problem on HackerEarth but as I submitted my solution most of the test cases were passed and the rest showed 'Time Limit Exceeded'. I would be very grateful if you could help me improve the algorithm of my code to reduce the runtime.

Following is the problem: Alice works as a restaurant manager. The restaurant has prepared 'N' lunch boxes and Alice plans to distribute them to some schools. Consider that there are 'M' schools and an i-th school orders A[i] lunch boxes.

She wants to distribute lunch boxes to as many schools as possible. Also, she has the following rule:

For an i-th school, she gives either zero or A[i] lunch boxes

Your task is to help Alice to determine the maximum number of schools that can get lunch boxes.

My code-

#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, m;
        scanf("%d", &n); 
        scanf("%d", &m); 
        int a[m];
        
        for (int i = 0; i < m; i++) {
            scanf("%d", &a[i]);   
        }
        
        for (int i = 0; i < m; i++) {
            for (int j = i + 1; j < m; j++) {
                if (a[i] > a[j]) {
                    int temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
       
        int sum = 0, count = 0;
        for (int i = 0; i < m; i++) {
            sum = sum + a[i];
            if (sum > n) {
                break;
            } else {
                while (sum <= n) {
                    count++;
                    break;
                }
            }
        }
        printf("%d\n", count);
    }
}

Upvotes: 1

Views: 177

Answers (1)

chqrlie
chqrlie

Reputation: 144740

The final loop should be simplified: the while (sum <= n) { count++; break; } is fully redundant and equivalent to count++;.

You can simply use i at the end of the loop:

    int i;
    int sum = 0;
    for (i = 0; i < m; i++) {
        sum = sum + a[i];
        if (sum > n) {
            break;
        }
    }
    printf("%d\n", i);

Regarding the time limit, it is possible that the test cases use large amounts of data, and the sort method you use has quadratic time complexity O(m2), causing the program to exceed the time limit.

You can use qsort to reduce the complexity to O(m*log(m)).

Here is a modified version:

#include <stdio.h>

int compare_ints(const void *a1, const void *a2) {
    const int *p1 = a1;
    const int *p2 = a2;
    return (*p1 > *p2) - (*p1 < *p2);
}

int main() {
    int t;
    if (scanf("%d", &t) != 1)
        return 1;

    while (t-- > 0) {
        int i, n, m;
        if (scanf("%d %d", &n, &m) != 2)
            return 1;

        int a[m];
        int sum = 0;
        for (i = 0; i < m; i++) {
            if (scanf("%d", &a[i]) != 1)
                return 1;
            sum += a[i];
        }

        if (sum > n) {
            /* all orders cannot be delivered: lets sort the array
             * to determine how many of the lowest orders can be delivered.
             * Optimisation inspired by EdHeal.
             */        
            qsort(t, sizeof(t[0]), m, compare_ints)
            sum = 0;
            for (i = 0; i < m; i++) {
                sum = sum + a[i];
                if (sum > n)
                    break;
            }
        }
        printf("%d\n", i);
    }
    return 0;
}

Upvotes: 1

Related Questions