0

I tried the question PS mentioned here.

Task.

You have a program which is parallelized and uses n independent threads to process the given list of m jobs. Threads take jobs in the order they are given in the input. If there is a free thread, it immediately takes the next job from the list.

If a thread has started processing a job, it doesn’t interrupt or stop until it finishes processing the job.

If several threads try to take jobs from the list simultaneously, the thread with smaller index takes the job. For each job you know exactly how long will it take any thread to process this job, and this time is the same for all the threads.

You need to determine for each job which thread will process it and when will it start processing.

Input Format.

The first line of the input contains integers n and m. The second line contains m integers t_i — the times in seconds it takes any thread to process i-th job. The times are given in the same order as they are in the list from which threads take jobs. Threads are indexed starting from 0.

Constraints.

1 ≤ n ≤ 10^5 ; 1 ≤ m ≤ 10^5 ; 0 ≤ t i ≤ 10^9 .

Output Format.

Output exactly m lines. i-th line (0-based index is used) should contain two space- separated integers — the 0-based index of the thread which will process the i-th job and the time in seconds when it will start processing that job.

My implementation works fine for basic test cases. However, this is going to fail in some test. What is the mistake that I didn't see here.

Sample Input

2 5

1 2 3 4 5

Output

0 0

1 0

0 1

1 2

0 4

Here's my code.

#include <iostream>
#include <queue>

using std::cin;
using std::cout;
using std::endl;
using std::ios_base;
using std::pair;
using std::priority_queue;
using std::queue;
using std::vector;

#define For(i,a,n) for (int i = a; i < n; i++)
typedef pair<int,int> PII;

int main() {

    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    
    int n,m,t,val;
    PII p;
    priority_queue<PII> pq;
    queue<int> q;

    // inputs >> number of treads, jobs
    cin >> n >> m;
    // time to process each job
    For(i,0,m){
        cin >> t;
        q.push(t);
    }
    // priority_queue
    // contains pair {-time, -tread} 
    For(i,0,n) pq.push({0, -i});

    // untill finish all jobs
    while(!q.empty()){
        // get the smallest time tread
        p = pq.top();
        pq.pop();
        // print the output << tread no , start time
        cout << -p.second << " " << -p.first << endl;
        // get the next value in the queue
        val = q.front();
        q.pop();
        // push the given tread with new end time
        pq.push({ -val + p.first, p.second });
        
    }

    return 0;
}

The following python3 code works fine for the problem. However, I cannot find any functionality difference in both of these. What is the problem with the c++ implementation.

import sys
import heapq

def read(): 
    return [int(i) for i in sys.stdin.readline().strip().split()]

n, m = read()
arr = read()

q = []

for i in range(n):
    heapq.heappush(q, (0, i))

for i in range(m):
    x, y = heapq.heappop(q)
    print(y, x)
    heapq.heappush(q, (x+arr[i], y))

Thank you for every answer.

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997

2 Answers2

1

I got the answer. That was because of the integer range in c++. Changing 'int' into 'long long' fixed the issue. Thanks.

0

If several threads try to take jobs from the list simultaneously, the thread with smaller index takes the job.

If two (or more) threads finish their jobs at the same time, you are not guaranteed that the thread you pop first has the minimal index among them. Fix is simple: pop all the threads, which terminate at that time, and sort them by index.

user58697
  • 6,907
  • 1
  • 11
  • 24