Build a String – HackerRank Solution

In this post, we will solve Build a String HackerRank Solution. This problem (Build a String) is a part of HackerRank Problem Solving series.

Solution – Build a String – HackerRank Solution

C++

#include <cstdio>
#include <algorithm>

using namespace std;

const int inf=1000000000;
struct suffix
{
    int s1,s2,poz;
    bool operator <(const suffix &aux) const
    {
        if(s1==aux.s1) return s2<aux.s2;
        else return s1<aux.s1;
    }
    bool operator ==(const suffix &aux) const
    {
        return s1==aux.s1 && s2==aux.s2;
    }
}s[30010];
struct arbint
{
    int minn,lazy;
}arb[200010];
int p[17][30010],logg[30010],pas[30010];
int poz[30010],st[30010],dr[30010],rmq[17][30010],n,sol;
char sir[30010];

int LCP(int x,int y)
{
    int rez=0;
    for(int i=logg[n];i>=0 && x<=n && y<=n;i--)
        if(p[i][x]==p[i][y]) {rez+=1<<i;x+=1<<i;y+=1<<i;}
    return rez;
}

void arbint_init(int nod,int st,int dr)
{
    arb[nod].minn=arb[nod].lazy=inf;
    if(st==dr) return;
    int mid=(st+dr)/2;
    arbint_init(nod*2,st,mid);
    arbint_init(nod*2+1,mid+1,dr);
}

void update(int nod,int st,int dr)
{
    arb[nod].minn=min(arb[nod].minn,arb[nod].lazy);
    if(st<dr)
    {
        arb[nod*2].lazy=min(arb[nod*2].lazy,arb[nod].lazy);
        arb[nod*2+1].lazy=min(arb[nod*2+1].lazy,arb[nod].lazy);
    }
}

void arbint_update(int nod,int st,int dr,int left,int right,int val)
{
    if(left<=st && dr<=right)
    {
        arb[nod].lazy=min(arb[nod].lazy,val);
        update(nod,st,dr);
        return;
    }
    update(nod,st,dr);
    int mid=(st+dr)/2;
    if(left<=mid) arbint_update(nod*2,st,mid,left,right,val);
    else update(nod*2,st,mid);
    if(mid<right) arbint_update(nod*2+1,mid+1,dr,left,right,val);
    else update(nod*2+1,mid+1,dr);
    arb[nod].minn=min(arb[nod*2].minn,arb[nod*2+1].minn);
}

void arbint_query(int nod,int st,int dr,int poz)
{
    update(nod,st,dr);
    if(st==dr)
    {
        sol=arb[nod].minn;
        return;
    }
    int mid=(st+dr)/2;
    if(poz<=mid) arbint_query(nod*2,st,mid,poz);
    else arbint_query(nod*2+1,mid+1,dr,poz);
}

int get_min(int x,int y)
{
    int lim=logg[y-x+1];
    return min(rmq[lim][x],rmq[lim][y-(1<<lim)+1]);
}

int main()
{
    //freopen("file.in", "r", stdin);
    //freopen("file.out", "w", stdout);
    int t;
    for(scanf("%d",&t);t;t--)
    {
        int cost1,cost2;
        scanf("%d%d%d\n%s",&n,&cost1,&cost2,sir+1);
        for(int i=2;i<=n;i++) logg[i]=logg[i/2]+1;
        for(int i=1;i<=n;i++)
        {
            p[0][i]=sir[i];
            s[i].poz=i;
        }
        for(int i=1;i<=logg[n]+1;i++)
        {
            for(int j=1;j<=n;j++)
            {
                s[j].s1=p[i-1][s[j].poz];
                if(s[j].poz+(1<<(i-1))<=n) s[j].s2=p[i-1][s[j].poz+(1<<(i-1))];
                else s[j].s2=-1;
            }
            sort(s+1,s+n+1);
            for(int j=1;j<=n;j++)
                if(j>1 && s[j]==s[j-1]) p[i][s[j].poz]=p[i][s[j-1].poz];
                else p[i][s[j].poz]=j;
        }
        for(int i=1;i<=n;i++) rmq[0][i]=s[i].poz;
        for(int i=1;i<=logg[n];i++)
        {
            int lim=n-(1<<(i-1))+1;
            for(int j=1;j<=lim;j++) rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
        }
        for(int i=1;i<=n;i++)
        {
            int st=1,dr=min(n-s[i].poz+1,s[i].poz-1);
            while(st<=dr)
            {
                int mid=(st+dr)/2,ok=0;
                int l=1,r=i-1;
                while(l<=r)
                {
                    int m=(l+r)/2;
                    if(get_min(m,i)<=s[i].poz-mid) l=m+1;
                    else r=m-1;
                }
                int a=r;
                l=i+1;r=n;
                while(l<=r)
                {
                    int m=(l+r)/2;
                    if(get_min(i,m)<=s[i].poz-mid) r=m-1;
                    else l=m+1;
                }
                int b=l;
                if(1<=a && LCP(s[a].poz,s[i].poz)>=mid) ok=1;
                if(b<=n && LCP(s[b].poz,s[i].poz)>=mid) ok=1;
                if(ok) st=mid+1;
                else dr=mid-1;
            }
            pas[s[i].poz]=dr;
        }
        arbint_init(1,1,n);
        arbint_update(1,1,n,1,1,cost1);
        for(int i=1;i<n;i++)
        {
            arbint_query(1,1,n,i);
            if(pas[i+1]) arbint_update(1,1,n,i+1,i+pas[i+1],sol+cost2);
            arbint_update(1,1,n,i+1,i+1,sol+cost1);
        }
        arbint_query(1,1,n,n);
        printf("%d\n",sol);
    }
    return 0;
}

Python

rep = int(input())
for r in range(rep):
    l, a, b = map(int, input().split(' '))
    s = input().strip()
    i = 1
    cost = 0
    cost = [float('inf')] * (l + 1)
    cost[0] = 0
    k = 0
    while i <= l: # i is the number of char finished, s[i-1] finished
        # find the maximun substring
        j = max(i, k)
        while j<=l and (s[i-1:j] in s[:i-1]):
            j += 1
        
        # s[i-1:j-1] in s
            
        if j-1 != i:
            cost[j-1] = min(cost[i-1] + b, cost[j-1])
            k = j
        cost[i] = min(cost[i-1] + a, cost[i])
        #print(cost)
        #print(s[i], a)
        i += 1
            
            
    print(cost[-1])
                     

Java

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
    
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        for(int t=0;t<T;t++){
            int N = sc.nextInt();
            int A = sc.nextInt();
            int B = sc.nextInt();
            String S = sc.next();
            System.out.println( buildStringCost(N,A,B,S) );
        }
    }
    
    public static int buildStringCost(int N, int A, int B, String S){
        int[] dp = new int[N];
        dp[0] = A;
        int lastL = 0;
        for(int k=1;k<N;++k){
            dp[k] = dp[k-1]+A;
            int L = lastL+1;
            while(L>0){
                String cur = S.substring(k-L+1, k+1);
                int idx = S.substring(0, k-L+1).indexOf(cur);
                if( -1==idx )
                    L--;
                else{
                    dp[k] = Math.min(dp[k], dp[k-L]+B);
                    break;
                }
            }
            lastL = L;
        }
        return dp[N-1];
    }
}

Note: This problem (Build a String) is generated by HackerRank but the solution is provided by CodingBroz. This tutorial is only for Educational and Learning purpose.

Leave a Comment

Your email address will not be published. Required fields are marked *