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.