Editorial - GYMTYM

PROBLEM LINK:

Gym Freaks

Author: chirag_mathur
Tester: hellb0y_suru
Editorialist: chirag_mathur

DIFFICULTY:

EASY

PROBLEM:

Given slots of Amit and Saurav
Saurav should shift his schedule by X which should be between L to R (inclusive) so that both can have the maximum common time.

Prerequisites:

  • A little amount of brain to be applied while solving or understanding the editorial :wink:

EXPLANATION:

It is a very simple question, just implement what is written in the question. Make a prefix array of the slot timings of Amit, then simply iterate the slots of Saurav for every value of X and check the common time for every value of X. Print X for which there is maximum common time.

SOLUTIONS:

Setter's Solution
#include <bits/stdc++.h>
using namespace std;
#define ll long long int

#define loop(a, b, i) for (ll i = a; i < b; i++)

int main()
{

   ll tc = 1;
   cin >> tc;
   while (tc--)
   {
       ll p, q, l, r;
       cin >> p >> q >> l >> r;
       vector<pair<ll, ll>> a(p), b(q);
       ll root[2004] = {0};
       loop(0, p, i)
       {
           cin >> a[i].first >> a[i].second;
           root[a[i].first]++;
           root[a[i].second + 1]--;
       }

       loop(1, 2004, i) root[i] += root[i - 1];
       loop(1, 2004, i) root[i] += root[i - 1];
       loop(0, q, i)
       {
           cin >> b[i].first >> b[i].second;
       }

       ll a2 = r - b[q - 1].second;
       ll ansf = 0, anst = 0;
       ll ind = l;
       loop(l, r + 1, i)
       {
           anst = 0;
           loop(0, q, j)
           {
               if (b[j].first + i - 1 >= 0)
                   anst += root[b[j].second + i] - root[b[j].first + i - 1];
               else
                   anst += root[b[j].second + i];
           }
           if (ansf < anst)
           {
               ansf = max(ansf, anst);
               ind = i;
           }
       }

       cout << ind << "\n";
   }

   return 0;
}

Tester's Solution
#include "bits/stdc++.h"
#define ll long long int
#define MOD 1000000007 
#define oo 1000000000000000000
#define forr(i,n) for(int i=0;i<n;i++)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define all(x) x.begin(),x.end()
#define eb emplace_back
#define FF first
#define SS second
#define mem(a,v) memset(a,v,sizeof(a))
#define pb push_back

using namespace std;


void __sol(){
   int p,q,l,r; cin >> p >> q >> l >>r;
   int a1[1010] , a2[1010];
   mem(a1,0);
   mem(a2,0);
   forr(i,p){
       int l,r; cin >> l >> r;
       a1[l]++;
       a1[r+1]--;
   }
   for(int i=1;i<=1000;i++) a1[i]+=a1[i-1];
   forr(i,q){
       int l,r; cin >> l >> r;
       a2[l]++;
       a2[r+1]--;
   }
   for(int i=1;i<=1000;i++) a2[i]+=a2[i-1];
   int max_time = -1 , x = 0;
   for(int i=l;i<=r;i++){
       int cnt = 0;
       for(int t=0;t<=1000;t++){
           if( t-i>=0 && a1[t]>0 && a2[t-i]>0 ) cnt++;
       }
       if(cnt > max_time){
           max_time = cnt;
           x = i;
       }
   }
   cout << x <<"\n";
   return;
}


int main(){    
   fastio;
   int tc=1;  cin >> tc;
   while(tc--) __sol();
   return 0;
}

Is multiple answer possible for this ? like two different values of X might give the maximum answer. Are the test cases such that the answer is unique?

Can anyone point out to me where I am going wrong, please ?

Solution in C++
#include <bits/stdc++.h>
using namespace std;

//----------------------------------- DEBUG -----------------------------------
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
// debug & operator << (debug & dd, P p) { dd << "(" << p.x << ", " << p.y << ")"; return dd; }

//----------------------------------- END DEBUG --------------------------------

// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html
template<class Fun> class y_combinator_result {
    Fun fun_;
public:
    template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
    template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); }
};
template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); }
 

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)

//----------------------------------- DEFINES ----------------------------------- 

#define sz(x) (int)(x).size()
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define ins insert
#define nl '\n'
#define Stringize( L )     #L 
#define MakeString( M, L ) M(L)
#define $Line MakeString( Stringize, __LINE__ )
#define Reminder __FILE__ "(" $Line ") : Warning: "

//----------------------------------- END DEFINES -------------------------------- 

//-------------------------- CUSTOM UNORDERED MAP HASH ---------------------------

struct custom_hash{
    static uint64_t splitmix64(uint64_t x){
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(uint64_t a) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(a + FIXED_RANDOM);
    }
    template<class T> size_t operator()(T a) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        hash<T> x;
        return splitmix64(x(a) + FIXED_RANDOM);
    }
    template<class T, class H> size_t operator()(pair<T, H> a) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        hash<T> x;
        hash<H> y;
        return splitmix64(x(a.first) * 37 + y(a.second) + FIXED_RANDOM);
    }
};
template<class T, class H>using umap=unordered_map<T,H,custom_hash>;

//----------------------- CUSTOM UNORDERED MAP HASH END--------------------------

void run_cases() {
    int P,Q,L,R;
    cin >> P >> Q >> L >> R;

    vector<pair<int,int>> A, B;

    for(int i=0;i<P;i++) {
        int l,r;
        cin >> l >> r;
        A.emplace_back(l, r);
    }
    // debug() << imie(A);

    for(int i=0;i<Q;i++) {
        int l, r;
        cin >> l >> r;
        B.emplace_back(l, r);
    }
    // debug() << imie(B);

    vector<pair<int,int>> scores;

    auto shift = [&](int x) -> vector<pair<int,int>> {
        vector<pair<int,int>> ans = B;
        for(int i=0;i<Q;i++) {
            if(ans[i].first + x > 1000) continue;
            ans[i].first = min(ans[i].first + x, 1000);
            ans[i].second = min(ans[i].second + x, 1000);

        }
        // debug() << imie(ans);
        return ans;
    };

    auto find_overlap = [&](pair<int,int> a, pair<int,int> b) -> int {
        pair<int,int> ans = {max(a.first, b.first), min(a.second, b.second)};
        return max(0, ans.second - ans.first + 1);
    };

    auto calculate_score = [&](vector<pair<int,int>> shifts) -> int {
        int score = 0;
        for(pair<int,int> u: A) {
            for(pair<int,int> v: shifts) {
                score += find_overlap(u, v);
            }
        }
        return score;
    };

    for(int x=L;x<=R;x++) {
        vector<pair<int,int>> shifts = shift(x);

        int score = calculate_score(shifts);
        scores.emplace_back(score, x);
    }
    sort(rall(scores));
    debug() << imie(scores);
    cout << scores[0].second << nl;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(nullptr);

    int tests = 1;
    cin >> tests;

    for(int test = 1;test <= tests;test++) {
        run_cases();
    }
}

In case of same answer for different X, we should choose smaller X.

1 Like

If there are multiple possible answers for different value of X, we have to choose the minimum value of X.

1 Like