1
\$\begingroup\$

I solved this problem from a challenge.The problem is as below:-

Problem Statement:

Given N activities with their start and finish times. Select the maximum number of activities that can be performed by a single person, assuming that a person can only work on a single activity at a time.

Note : The start time and end time of two activities may coincide.

Input: The first line contains T denoting the number of testcases. Then follows description of testcases. First line is N number of activities then second line contains N numbers which are starting time of activies.Third line contains N finishing time of activities.

Output: For each test case, output a single number denoting maximum activities which can be performed in new line.

Constraints:

1<=T<=50
1<=N<=1000
1<=A[i]<=100

Example:

Input:

2
6
1 3 2 5 8 5
2 4 6 7 9 9
4
1 3 2 5
2 4 3 6

Output:

4
4

C++ code for the problem:-

#include<iostream>
void swap(int a[],int i,int j)
{
    int temp=a[i];
    a[i]=a[j];
    a[j]=temp;
}
int activitySelection(int start[], int end[], int n){

    long i,j,count=1,pointer;
    for(i=0;i<n;i++)         //sorting both arrays in the order of the end array
    {
        for(j=i+1;j<n;j++)
        if(end[j]<end[i])
        {
            swap(end,i,j);
            swap(start,i,j);
        }

    }
    pointer=end[0];  //pointer set to end time of the first activity 
    for(i=1;i<n;i++)
    {
        if(start[i]>=pointer) //if 
        {
            count++;

            pointer=end[i];
        }

    }
    return count;
}
int main()
{
  int t;
  std::cin>>t; /*number of testcases*/
  while(t--)
  {
    int n;
    std::cin >> n;
    int start[n], end[n];
    for(int i=0;i<n;i++)
        std::cin>>start[i];
    for(int i=0;i<n;i++)
        std::cin>>end[i];

   std:: cout << activitySelection(start, end, n) << std::endl;
  }
}

The code works as I intended to.But there are few openings that i feel could be improved in the code.The above code basically sorts the both arrays according to the end[] array.Then it checks if the starting time of the current activity is greater or equal to the end time of the previous activity,if yes then count increments and the pointer is set to the end time of the current activity for comparing the next activity.Two things i want to know:

1.Is there a better approach than sorting arrays and comparing?

2.What is a better way to sort the two arrays on the basis of the second array?

Please suggest changes to improve.Thanks for reading ;-)

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Note: your code doesn't currently compile for at least two reasons: you are not telling the compiler cout and endl live in the std namespace, and you can't declare your arrays start and end because n is not known at compile-time (instead, you'd have to use dynamic memory allocations).

In any case, your code smells like your background might be in C (but then you'd probably also know about dynamic memory... well, anyway). Indeed, with C++, you typically define variables as close to their site of usage. Moreover, you could take advantage of the algorithms and data structures provided by the language.

  1. Is there a better approach than sorting arrays and comparing?

Essentially no: you must sort the arrays (with no additional knowledge, you can't beat the log-linear bound). This dominates your runtime, but it is scalable and practical enough that you don't have to worry about it.

  1. What is a better way to sort the two arrays on the basis of the second array?

Because start and end times are logically and tightly coupled (i.e., something is wrong if we suddenly lose the correspondence), it's a good idea to tie them together. For that reason, we can use std::pair. To store such objects, we can use a dynamic array, i.e., std::vector. For sorting that according to the second element, we can use std::sort.

To summarize, we could proceed along the following lines (I'm taking the liberty to omit reading input to avoid clutter):

#include <iostream>
#include <algorithm>
#include <vector>

typedef std::vector<std::pair<int, int> > PairList;

int activitySelection(const PairList& p) 
{
    PairList s(p);
    std::sort(s.begin(), s.end(), [](const auto& x, const auto& y) {
        return x.second < y.second;
    });

    int end = s[0].second;
    int count = 1;

    for (int i = 1; i < s.size(); ++i)
    {
        if (s[i].first >= end)
        {
            ++count;
            end = s[i].second;
        }
    }

    return count;
}

int main()
{
    PairList v{ {1,2},{3,4},{2,6},{5,7},{8,9},{5,9} };
    std::cout << activitySelection(v) << "\n";
}
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the answer and the cout and endl part was my mistake while editing(I corrected them now) and the variable array size was not written by me, infact the whole main function was provided by the platform and there was no rewrite permission.I just copied it. \$\endgroup\$ Commented Aug 29, 2019 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.