Search code examples
c++vectordata-structurestime-complexity

Time Complexity of my program in competitive programming question City Plan


F. City Plan

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

Problem Description: There are ๐‘› houses in one particular city that were built along one straight road. For simplicity, we can say that the ๐‘–-th house is located at integer point ๐‘ฅ๐‘– (0โ‰ค๐‘ฅ๐‘–โ‰ค10^9, all ๐‘ฅ๐‘– are distinct).

You are participating in one project, and you were asked to calculate for each house ๐‘– the distance ๐‘‘๐‘– from the ๐‘–-th house to the farthest other house.

Let's say that the distance between the houses ๐‘– and ๐‘˜ is equal to |๐‘ฅ๐‘–โˆ’๐‘ฅ๐‘˜|, where |๐‘Ž| is the absolute value of ๐‘Ž. Then ๐‘‘๐‘– can be calculated as max1โ‰ค๐‘˜โ‰ค๐‘›(|๐‘ฅ๐‘–โˆ’๐‘ฅ๐‘˜|).

Spending some time, you finally calculated all ๐‘› values ๐‘‘1,๐‘‘2,โ€ฆ,๐‘‘๐‘›. But, at the same time, you've lost a piece of paper containing a list of all house positions ๐‘ฅ๐‘–.

You are too lazy to measure all house positions, and you believe that actual house positions are not so important for the project. So the question is: can you create an array ๐‘ฅ1,๐‘ฅ2,โ€ฆ,๐‘ฅ๐‘› that is consistent with the array ๐‘‘ you've calculated?

Input: The first line contains a single integer ๐‘ก (1โ‰ค๐‘กโ‰ค10^4) โ€” the number of test cases. Next ๐‘ก cases follow.

The first line of each test case contains the single integer ๐‘› (2โ‰ค๐‘›โ‰ค2โ‹…10^5) โ€” the number of houses in the city.

The second line of each test case contains ๐‘› integers ๐‘‘1,๐‘‘2,โ€ฆ,๐‘‘๐‘› (1โ‰ค๐‘‘๐‘–โ‰ค10^7), where ๐‘‘๐‘– is the maximum distance from house ๐‘– to some other house.

Additional constraints on the input:

  • The array ๐‘‘ is correct, i. e. there exists at least one array ๐‘ฅ that is consistent with array ๐‘‘.
  • The total sum of ๐‘› among all test cases doesn't exceed 2โ‹…105.

Output: For each test case, print ๐‘› integers ๐‘ฅ1,๐‘ฅ2,โ€ฆ,๐‘ฅ๐‘› (0โ‰ค๐‘ฅ๐‘–โ‰ค10^9) โ€” the positions of houses that produce the given array ๐‘‘. All ๐‘ฅ๐‘– must be distinct.

If there are several solutions, print any. Note that the order of ๐‘ฅ๐‘– matters since it affects the value of ๐‘‘๐‘–.

I wrote a solution that runs in O(n) time but I am still getting TLE. Maybe there something wrong I might be doing?? I am confused

Here is my soution

#include <bits/stdc++.h>

using namespace std;

void solve() {
    int n, maximum = -1;
    cin >> n;
    vector<int> a(n, 0);

    for (int i=0; i < n; ++i) {
        cin >> a[i];
        maximum = max(a[i], maximum);
    }

    vector<bool> mark(maximum + 1, 0);
    for (int i=0; i < n; ++i) {
        if (mark[maximum - a[i]])
            cout << 0 + a[i] << " ";
        else {
            cout << maximum - a[i] << " ";
            mark[maximum - a[i]] = 1;
        }
    }
    cout << '\n';
    return;
}   
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve(); 
    return 0;
}


Solution

  • #include <bits/stdc++.h>
    #include <unordered_set>
    
    using namespace std;
    
    void solve() {
        int n, maximum = -1;
        cin >> n;
        int a[n];
    
        for (int i=0; i < n; ++i) {
            cin >> a[i];
            maximum = max(a[i], maximum);
        }
    
        //bool mark[maximum+1];
        // for (int i=0; i < maximum+1; ++i) 
        //  mark[i] = 0;
    
        unordered_set<int> mark;
        
        // vector<bool> mark(maximum + 1, 0);
        for (int i=0; i < n; ++i) {
            if (mark.count(maximum - a[i]))
                cout << a[i] << " ";
            else {
                cout << maximum - a[i] << " ";
                mark.insert(maximum - a[i]);
            }
        }
        cout << '\n';
        return;
    }
        
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--)
            solve(); 
        return 0;
    }
    

    I used this for submission.

    When I used bool array(commented in the code) It causes a segmentation fault for the test

    1
    2
    10000000 10000000
    

    When I used vector<bool>(commented in the code) the code works as expected but causes TLE at 2000ms.

    When I used unordered_set<int>(used in the code) the submission was successful and ran under 109 ms.

    The only change in the code was the declaration of mark as bool[], vector and unordered_set and this code below

    for bool[] and vector<bool> I used

    for (int i=0; i < n; ++i) {
        if (mark[maximum - a[i]])
            cout << 0 + a[i] << " ";
        else {
            cout << maximum - a[i] << " ";
            mark[maximum - a[i]] = 1;
        }
    }
    

    I was still directly accessing indices after calculating maximum - a[i].

    I knew vector was slow but couldn't figure out why bool[] was getting a segmentation fault.

    I was sure it would work because I used the exact same logic for the bool[] and the vector<bool>. Not a single change.