Skip to content
TheCScience
TheCScience

Everything About Education

  • Pages
    • About US
    • Contact US
    • Privacy Policy
    • DMCA
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms Problems Solutions
    • HackerRank C solutions
    • HackerRank C++ problems solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
TheCScience
TheCScience

Everything About Education

HackerRank Ticket Problem Solution

Yashwant Parihar, June 2, 2023May 28, 2024

In this post, we will solve HackerRank Ticket Problem Solution.

There are n people at the railway station, and each one wants to buy a ticket to go to one of k different destinations. Then people are in a queue.
There are m ticket windows from which tickets can be purchased. Then people will be distributed in the windows such that the order is maintained. In other words, suppose we number the people 1 ton from front to back. If person i and person j go to the same window and i < j, then person i should still be ahead of person j in the window.
Each ticketing window has an offer. If a person in the queue shares the same destination as the person immediately in front of him/her, a 20% reduction in the ticket price is offered to him/her.
For example, suppose there are 3 people in the queue for a single ticket window, all with the same destination which costs 10 bucks. Then the first person in the queue pays 10 bucks, and the 2nd and 3rd persons get a discount of 20% on 10 bucks, so they end up paying 8 bucks each instead of 10 bucks.
Try to distribute then people across the m windows such that the total cost $ paid by all n people is minimized.

Input Format
The first line contains 3 integers:

  • n is the number of people
  • m is the number of ticket windows
  • k is the number of destinations separated by a single space (in the same order)


Then k lines follow. The ith line contains an alphanumeric string place, and an integer price:
place, is the ith destination

  • price, is the ticket price for place.

Then n lines follow. The ith line contains an alphanumeric string destination, which is the destination of the ith person.

Sample Input

5 2 3
CALIFORNIA 10
HAWAII 8
NEWYORK 12
NEWYORK
NEWYORK
CALIFORNIA
NEWYORK
HAWAII

Sample Output

49.2
1
1
2
1
1

Explanation
At the beginning, all the people are in the same queue, and will go to the ticket windows one by one in the initial order.
{1, 2, 4, 5} will buy ticket in the first window.
{3} will buy ticket in the second window.
In the first ticket window, #1 will pay 12 bucks to go to NEWYORK, and #2 and #4 have the same destination with the person in front of them, so they will get 20% off, and will pay 9.6 bucks each. #5 has a different destination, so it will cost him 8 bucks to go to HAWAII.
In the second ticket window, #3 will pay 10 bucks to go to CALIFORNIA.

HackerRank Ticket Problem Solution
HackerRank Ticket Problem Solution

Ticket C Solution

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 510
#define INF 100000000
#define E 0.0001
#define MAX 60000
double cost[N][N], lx[N], ly[N], slack[N], price[100];
int n, max_match, xy[N], yx[N], S[N], T[N], slackx[N], prev[N], d[500], ans[500];
char dd[100][200], ds[200];
int equal(double x, double y)
{
    if( y - x < E && x - y < E )
    {
        return 1;
    }
    return 0;
}
void init_labels()
{
    int x, y;
    for( x = 0 ; x < N ; x++ )
    {
        lx[x] = ly[x] = 0;
    }
    for( x = 0 ; x < n ; x++ )
    {
        for( y = 0 ; y < n ; y++ )
        {
            lx[x] = ( lx[x] > cost[x][y] ) ? lx[x] : cost[x][y];
        }
    }
}
void augment()
{
    if( max_match == n )
    {
        return;
    }
    int x, y, root, q[N], wr = 0, rd = 0;
    memset(S, 0, sizeof(S));
    memset(T, 0, sizeof(T));
    memset(prev, -1, sizeof(prev));
    for( x = 0 ; x < n ; x++ )
    {
        if( xy[x] == -1 )
        {
            q[wr++] = root = x;
            prev[x] = -2;
            S[x] = 1;
            break;
        }
    }
    for( y = 0 ; y < n ; y++ )
    {
        slack[y] = lx[root] + ly[y] - cost[root][y];
        slackx[y] = root;
    }
    while(1)
    {
        while( rd < wr )
        {
            x = q[rd++];
            for( y = 0 ; y < n ; y++ )
            {
                if( equal(cost[x][y] , lx[x] + ly[y]) &&  !T[y] )
                {
                    if( yx[y] == -1 )
                    {
                        break;
                    }
                    T[y] = 1;
                    q[wr++] = yx[y];
                    add_to_tree(yx[y], x);
                }
            }
            if( y < n )
            {
                break;
            }
        }
        if( y < n )
        {
            break;
        }
        update_labels();
        wr = rd = 0;                
        for( y = 0 ; y < n ; y++ )
        {
            if( !T[y] &&  equal(slack[y] , 0) )
            {
                if( yx[y] == -1 )
                {
                    x = slackx[y];
                    break;
                }
                else
                {
                    T[y] = 1;
                    if(!S[yx[y]])    
                    {
                        q[wr++] = yx[y];
                        add_to_tree(yx[y], slackx[y]);
                    }
                }
            }
        }
        if( y < n )
        {
            break;
        }
    }
    if( y < n )
    {
        int cx, cy, ty;
        max_match++;
        for( cx = x, cy = y ; cx != -2 ; cx = prev[cx], cy = ty )
        {
            ty = xy[cx];
            yx[cy] = cx;
            xy[cx] = cy;
        }
        augment();
    }
}
void update_labels()
{
    int x, y;
    double delta = INF;
    for( y = 0 ; y < n ; y++ )
    {
        if(!T[y])
        {
            delta = ( delta < slack[y] ) ? delta : slack[y];
        }
    }
    for( x = 0 ; x < n ; x++ )
    {
        if(S[x])
        {
            lx[x] -= delta;
        }
    }
    for( y = 0 ; y < n ; y++ )
    {
        if(T[y])
        {
            ly[y] += delta;
        }
    }
    for( y = 0 ; y < n ; y++ )
    {
        if(!T[y])
        {
            slack[y] -= delta;
        }
    }
}
void add_to_tree(int x, int prevx) 
{
    int y;
    S[x] = 1;
    prev[x] = prevx;
    for( y = 0 ; y < n ; y++ )
    {
        if( lx[x] + ly[y] - cost[x][y] < slack[y] )
        {
            slack[y] = lx[x] + ly[y] - cost[x][y];
            slackx[y] = x;
        }
    }
}
double hungarian()
{
    double ret = 0;
    max_match = 0;
    memset(xy, -1, sizeof(xy));
    memset(yx, -1, sizeof(yx));
    init_labels();
    augment();
    int x;
    for( x = 0 ; x < n ; x++ )
    {
        ret += cost[x][xy[x]];
    }
    return ret;
}
int main()
{
    double a = 0;
    int nn, m, k, i, j, t;
    scanf("%d%d%d", &nn, &m, &k);
    for( i = 0 ; i < k ; i++ )
    {
        scanf("%s%lf", &dd[i][0], price+i);
    }
    for( i = 0 ; i < nn ; i++ )
    {
        scanf("%s", ds);
        for( j = 0 ; j < k ; j++ )
        {
            if( strcmp(ds, &dd[j][0]) == 0 )
            {
                d[i] = j;
                break;
            }
        }
    }
    n = nn + m;
    for( i = 0 ; i < n ; i++ )
    {
        for( j = 0 ; j < n ; j++ )
        {
            if( j < m || j <= i )
            {
                cost[i][j] = 0;
            }
            else if( i < m || d[i-m] != d[j-m] )
            {
                cost[i][j] = MAX - price[d[j-m]];
            }
            else
            {
                cost[i][j] = MAX - price[d[j-m]] * 0.8;
            }
        }
    }
    a = hungarian();
    for( i = 0 ; i < m ; i++ )
    {
        if(equal(cost[i][xy[i]], 0))
        {
            continue;
        }
        t = xy[i];
        while(1)
        {
            ans[t-m] = i + 1;
            if(equal(cost[t][xy[t]], 0))
            {
                break;
            }
            t = xy[t];
        }
    }
    printf("%.3lf\n", MAX * (double)nn - a);
    for( i = 0 ; i <nn ; i++ )
    {
        printf("%d\n", ans[i]);
    }
    return 0;
}

Ticket C++ Solution

/*Ticket*/
#include <bits/stdc++.h>
using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)
#define SIZE(x) (sizeof(x)/sizeof(*x))

const int N = 500, V = N*2+2;
const double EPS = 1e-8;
string dest[N];
bool in[V];
int q[V], window[N];
double dist[V];
struct Edge {
    int v, c;
    double w;
    Edge *next, *twain;
} *es[V], *pred[V], pool[N*(N-1)+3*N << 1], *allo = pool;

void add(int u, int v, int c, double w) {
    allo[0] = {v, c, w, es[u], allo+1};
    allo[1] = {u, 0, - w, es[v], allo};
    es[u] = allo++;
    es[v] = allo++;
}

bool labelCorrecting(int n, int src, int sink) {
    fill_n(in, n, false);
    fill_n(pred, n, nullptr);
    fill_n(dist, n, numeric_limits<double>::max());
    dist[src] = 0;
    int *fr = q, *re = q;
    *re++ = src;
    while (fr != re) {
        int u = *fr++;
        if (fr == q+SIZE(q))
            fr = q;
        in[u] = false;
        for (Edge *e = es[u]; e; e = e->next)
            if (e->c > 0) {
                double t = dist[u]+e->w;
                if (t+EPS < dist[e->v]) {
                    dist[e->v] = t;
                    pred[e->v] = e;
                    if (! in[e->v]) {
                        in[e->v] = true;
                        *re++ = e->v;
                        if (re == q+SIZE(q))
                            re = q;
                    }
                }
            }
    }
    return dist[sink] < numeric_limits<double>::max();
}

double minCostMaxFlow(int n, int src, int sink, int m) {
    int flow = 0;
    double cost = 0;
    while (flow < m && labelCorrecting(n, src, sink) && dist[sink] < 0) {
        int f = m-flow;
        for (int v = sink; v != src; v = pred[v]->twain->v)
            f = min(f, pred[v]->c);
        flow += f;
        cost += f*dist[sink];
        for (int v = sink; v != src; v = pred[v]->twain->v) {
            pred[v]->c -= f;
            pred[v]->twain->c += f;
        }
    }
    return cost;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, m, k;
    cin >> n >> m >> k;
    map<string, int> price;
    REP(i, k) {
        int p;
        cin >> dest[0] >> p;
        price[dest[0]] = p;
    }
    int src = 2*n, sink = src+1;
    REP(i, n) {
        cin >> dest[i];
        double t = price[dest[i]];
        add(src, i, 1, t);
        add(i, n+i, 1, -100*n);
        add(n+i, sink, 1, 0);
        REP(j, i)
            add(n+j, i, 1, dest[j] == dest[i] ? 0.8*t : t);
    }
    cout << minCostMaxFlow(sink+1, src, sink, m)+100*n*n << '\n';
    int id = 0;
    for (Edge *e = es[src]; e; e = e->next)
        if (e->c == 0)
            window[e->v] = ++id;
    REP(i, n)
        for (Edge *e = es[n+i]; e; e = e->next)
            if (e->v < n && i < e->v && e->c == 0)
                window[e->v] = window[i];
    REP(i, n)
        cout << window[i] << '\n';
}

Ticket C Sharp Solution

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

class MCMF {
    public const int MAXV=10000;
    public const long inff = 0x3f3f3f3f;
    public const long infc = 0x3f3f3f3f;
    int nv, ne, src, sink;
    int[] from, to, next, Q = new int[MAXV], head = new int[MAXV], prev = new int[MAXV], pe = new int[MAXV];
    long[] flow, cap, cost, d=new long[MAXV];
    bool[] InQ = new bool[MAXV];

    public MCMF(int n, int s, int t)
    {
        int MAXE = Math.Min( n*n,500000);
        from=new int[MAXE];
        to=new int[MAXE];
        next = new int[MAXE];
        flow = new long[MAXE];
        cap=new long[MAXE];
        cost=new long[MAXE];
        nv = n; src = s; sink = t; ne = 0;
        for(int i = 0; i < nv; i++) 
            head[i] = -1;
    }

    public void add(int u, int v, long c, long w) 
    {
        from[ne] = u; to[ne] = v; cap[ne] = c; cost[ne] = +w; flow[ne] = 0; next[ne] = head[u]; head[u] = ne++;
        from[ne] = v; to[ne] = u; cap[ne] = 0; cost[ne] = -w; flow[ne] = 0; next[ne] = head[v]; head[v] = ne++;
    }

    bool spfa() 
    {
        for(int i = 0; i < nv; i++) {
            prev[i] = -1; InQ[i] = false; d[i] = infc;
        }
        d[src] = 0; InQ[src] = true; Q[0] = src;
        int f = 0,r = 1;
        while(f != r) {
            int x = Q[f++];
            if(f == MAXV) 
                f = 0;
            InQ[x] = false;
            if(x == sink) continue;
            for(int k = head[x]; k != -1; k = next[k]) {
                int y = to[k];
                if(flow[k] < cap[k] && d[y] > cost[k] + d[x]) {
                    d[y] = cost[k] + d[x];
                    if(!InQ[y]) {
                        InQ[y] = true;
                        Q[r++] = y;
                        if(r == MAXV) 
                            r = 0;
                    }
                    prev[y] = x;
                    pe[y] = k;
                }
            }
        }
        return -1 != prev[sink];
    }

    public long minCostmaxFlow() 
    {
        long mflow=0, mcost=0;
        while (spfa())
        {
            var expand = inff;
            for(int k = sink; k != src; k = prev[k])
                if(expand > cap[pe[k]] - flow[pe[k]]) 
                    expand = cap[pe[k]] - flow[pe[k]];
            for(int k = sink; k != src; k = prev[k]){
                flow[pe[k]] += expand;
                flow[pe[k] ^ 1] -= expand;
            }
            if(d[sink] >= 0) break;
            mflow += expand;
            mcost += d[sink] * expand;
        }
        return mcost;
    }
    public int[] Prev()
    {
        var prev = new int[nv];
        for (int i = 0; i < ne; i++)
        {
            int from = this.from[i] / 2;
            int to = this.to[i] / 2;
            if (flow[i] > 0)
                prev[to] = from;
        }
        return prev;
    }
};
//
static class Program
{
    static void Main(string[] args)
    {
# if DEBUG
        Console.SetIn(new StreamReader(args[0]));
        var t0 = DateTime.Now;
# endif
        var s = Console.ReadLine().Trim().Split();
        var n_people=int.Parse(s[0]);
        var n_window=int.Parse(s[1]);
        var n_dest = int.Parse(s[2]);
        Dictionary<string, int> map=new Dictionary<string,int>();
        var price_1 = new int[n_dest];
        var price_2 = new int[n_dest];
        for (int i = 0; i < n_dest; i++)
        {
            s = Console.ReadLine().Trim().Split();
            map[s[0]] = i;
            var p = int.Parse(s[1]);
            price_2[i] = p * 8;
            price_1[i] = p * 10;
        }
        var dest = new int[n_people];
        for (int i = 0; i < n_people; i++)
            dest[i] = map[Console.ReadLine().Trim()];
        //
        int S1 = 2 * n_people, S = S1 + 1, T = S + 1;
        var mm=new MCMF(T + 1, S, T);
        mm.add(S, S1, n_window, 0);
        for (int i = 0; i < n_people; i++) 
            mm.add(2 * i, 2 * i + 1, 1, -MCMF.infc);
        for (int i = 0; i < n_people; i++) 
            mm.add(S1, 2 * i, 1, price_1[dest[i]]);
        for (int i = 0; i < n_people; i++) 
            mm.add(2 * i + 1, T, 1, 0);
        for (int i = 0; i < n_people; i++)
            for (int j = i + 1; j < n_people; j++)
            {
                if (dest[i] == dest[j]) 
                    mm.add(2 * i + 1, 2 * j, 1, price_2[dest[j]]);
                else 
                    mm.add(2 * i + 1, 2 * j, 1, price_1[dest[j]]);
            }
        var cost = mm.minCostmaxFlow();
        var ret = cost + n_people * MCMF.infc;
        Console.WriteLine(ret / 10.0);
        var prev = mm.Prev();
        int[] id = new int[n_people];
        for (int ct=1,i = 0; i < n_people; i++)
            if (prev[i] >= n_people)
                id[i] = ct++;
            else
                id[i] = id[prev[i]];
        foreach (var i in id)
            Console.WriteLine(i);
# if DEBUG
    Console.WriteLine(DateTime.Now.Subtract(t0));
# endif
    }
}

Ticket Java Solution

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

public class Solution {

  static class Edge {
    int v;
    int c;
    double w;
    Edge next;
    Edge twain;
    public Edge(int v, int c, double w) {
      this.v = v;
      this.c = c;
      this.w = w;
    }
  }
  
  static Edge[] es;
  static Edge[] pred;
  static Edge[] pool;
  static int allo = 0;

  static void add(int u, int v, int c, double w) {
    Edge e1 = new Edge(v, c, w);
    Edge e2 = new Edge(u, 0, -w);
    
    pool[allo] = e1;
    pool[allo].next = es[u];
    pool[allo].twain = e2;
    
    pool[allo+1] = e2;
    pool[allo+1].next = es[v];
    pool[allo+1].twain = e1;

    es[u] = pool[allo++];
    es[v] = pool[allo++];
  }

  static final double EPS = 1e-8;
  static boolean[] in;
  static int[] q;
  static double[] dist;
  
  static boolean labelCorrecting(int n, int src, int sink) {
    Arrays.fill(in, 0, n, false);
    Arrays.fill(pred, 0, n, null);
    Arrays.fill(dist, 0, n, Double.MAX_VALUE/2);
    dist[src] = 0;
    int fr = 0;
    int re = 0;
    q[re++] = src;
    while (fr != re) {
      int u = q[fr++];
      if (fr == q.length) {
        fr = 0;
      }
      in[u] = false;
      for (Edge e = es[u]; e != null; e = e.next) {
        if (e.c > 0) {
          double t = dist[u]+e.w;
          if (t + EPS < dist[e.v]) {
            dist[e.v] = t;
            pred[e.v] = e;
            if (! in[e.v]) {
              in[e.v] = true;
              q[re++] = e.v;
              if (re == q.length)
                re = 0;
            }
          }
        }
      }
    }
    return dist[sink] < Double.MAX_VALUE;
  }

  static double minCostMaxFlow(int n, int src, int sink, int m) {
    int flow = 0;
    double cost = 0;
    while (flow < m && labelCorrecting(n, src, sink) && dist[sink] < 0) {
      int f = m-flow;
      for (int v = sink; v != src; v = pred[v].twain.v) {
        f = Math.min(f, pred[v].c);
      }
      flow += f;
      cost += f*dist[sink];
      for (int v = sink; v != src; v = pred[v].twain.v) {
        pred[v].c -= f;
        pred[v].twain.c += f;
      }
    }
    return cost;
  }
  
  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

    StringTokenizer st = new StringTokenizer(br.readLine());
    int n = Integer.parseInt(st.nextToken());
    int m = Integer.parseInt(st.nextToken());
    int k = Integer.parseInt(st.nextToken());
    Map<String, Integer> price = new HashMap<>();
    for (int i = 0; i < k; i++) {
      st = new StringTokenizer(br.readLine());
      String s = st.nextToken();
      int p = Integer.parseInt(st.nextToken());
      price.put(s, p);
    }
    int src = 2*n;
    int sink = src+1;
    String[] dest = new String[n];
    es = new Edge[n*2+2];
    pred = new Edge[n*2+2];
    pool = new Edge[n*(n-1)+3*n << 1];
    for (int i = 0; i < n; i++) {
      st = new StringTokenizer(br.readLine());
      String s = st.nextToken();
      dest[i] = s;
      double t = price.get(s);
      add(src, i, 1, t);
      add(i, n+i, 1, -100*n);
      add(n+i, sink, 1, 0);
      for (int j = 0; j < i; j++) {
        add(n+j, i, 1, dest[j].equals(dest[i]) ? 0.8*t : t);
      }
    }
    in = new boolean[n*2+2];
    q = new int[n*2+2];
    dist = new double[n*2+2];
    double res = minCostMaxFlow(sink+1, src, sink, m)+100*n*n;
    DecimalFormat df = new DecimalFormat("#.###");
    bw.write(df.format(res) + "\n");
    int id = 0;
    int[] window = new int[n];
    for (Edge e = es[src]; e != null; e = e.next) {
      if (e.c == 0) {
        window[e.v] = ++id;
      }
    }
    for (int i = 0; i < n; i++) {
      for (Edge e = es[n+i]; e != null; e = e.next) {
        if (e.v < n && i < e.v && e.c == 0) {
          window[e.v] = window[i];
        }
      }
    }
    for (int i = 0; i < n; i++) {
      bw.write(window[i] + "\n");
    }

    bw.newLine();
    bw.close();
    br.close();
  }
}
c C# C++ HackerRank Solutions java CcppCSharpHackerrank Solutionsjava

Post navigation

Previous post
Next post

Similar websites

  • Programming
  • Data Structures
©2025 TheCScience | WordPress Theme by SuperbThemes