Magic strings, invented by the Bytelandians, are strings that contain immense ma
ID: 3557576 • Letter: M
Question
Magic strings, invented by the Bytelandians, are strings that contain immense magical power within themselves. Magic strings could bring luck and happiness to the Bytelandian citizens. Formally, a string S of length n is a magic string if it satisfies the following conditions:
(Si (1 ? i ? n) denotes the ith character of S). For example, the word "difference" is a magic string, while "similar" is not.
Given a string S of lowercase English letters, write a program to find the longest magic string than can be obtained by removing some letters of S. If there are more than one solutions, choose the longest magic string which is lexicographically smallest.
The first line contains t, the number of test cases (about 10). Then t test cases follow. Each test case contains a string S written in a single line. S does not contain more than 2000 letters.
Explanation / Answer
#include <stdio.h>
#include <string.h>
char ch;
#define MAXN 2005
char a[MAXN], s[MAXN];
char half[MAXN], mhalf[MAXN], shalf[MAXN];
int todel[MAXN][MAXN][2];
int len[MAXN][MAXN][2];
int sick[MAXN][MAXN][2];
int n;
main(void){
int i, j, k, q, t, tm;
scanf("%d", &t);
while(t--){
scanf("%s", &a[0]);
n = strlen(a);
for(i = 0; i <= n; i++) todel[i][i][0] = 0, todel[i][i][1] = 0, len[i][i][0] = 1, len[i][i][1] = 1;
for(i = 0; i < n; i++) todel[i + 1][i][0] = 0, todel[i + 1][i][1] = 0;
for(i = n - 1; i >= 0; i--) for(j = i + 1; j < n; j++) for(k = 0; k <= 1; k++){
todel[i][j][k] = 1000000000;
if(k & 1){
if(a[i] > a[j]) todel[i][j][k] = todel[i + 1][j - 1][1 - k];
tm = todel[i + 1][j][k];
if(todel[i][j - 1][k] < tm) tm = todel[i][j - 1][k];
tm++;
if(todel[i][j][k] < tm) tm = todel[i][j][k];
todel[i][j][k] = tm;
len[i][j][k] = j - i + 1 - todel[i][j][k];
}
else{
if(a[i] < a[j]) todel[i][j][k] = todel[i + 1][j - 1][1 - k];
tm = todel[i + 1][j][k];
if(todel[i][j - 1][k] < tm) tm = todel[i][j - 1][k];
tm++;
if(todel[i][j][k] < tm) tm = todel[i][j][k];
todel[i][j][k] = tm;
len[i][j][k] = j - i + 1 - todel[i][j][k];
}
}
if(len[0][n - 1][0] == 1){
char cur = '{';
for(i = 0; i < n; i++) if(a[i] < cur) cur = a[i];
printf("%c ", cur);
}
else{
int hcnt = 0;
int ans = len[0][n - 1][0], m = 0, lo = 0, hi = n - 1 , rem = ans, nc = 0, x, y;
char isok = 'a';
while(lo <= hi){
if(len[lo][hi][m] <= 1) break;
x = -1;
for(k = lo; k <= hi; k++){
if(a[k] == isok){
x = k;
break;
}
}
if(x == -1){
isok++;
continue;
}
y = -1;
if(m & 1){
for(k = hi; k > x; k--){
if(a[k] < isok){
y = k;
break;
}
}
}
else{
for(k = hi; k > x; k--){
if(a[k] > isok){
y = k;
break;
}
}
}
if(y == -1){
isok++;
continue;
}
if(len[x + 1][y - 1][1 - m] + 2 == rem){
rem -= 2;
half[hcnt++] = isok;
isok = 'a';
lo = x + 1, hi = y - 1;
m = 1 - m;
}
else{
isok++;
continue;
}
}
half[hcnt] = '';
for(i = 0; i <= hcnt; i++) s[i] = half[i];
int N = strlen(s);
for(i = lo; i <= n; i++) sick[0][i][0] = 0, sick[0][i][1] = 0;
for(j = 0; j <= N; j++) sick[j][n][0] = 0, sick[j][n][1] = 0;
for(i = 1; i <= N; i++) for(j = n - 1; j >= lo; j--) for(k = 0; k <= 1; k++){
if(k & 1){
if(s[i - 1] > a[j]) sick[i][j][k] = 1 + sick[i - 1][j + 1][1 - k];
else sick[i][j][k] = sick[i][j + 1][k];
}
else{
if(s[i - 1] < a[j]) sick[i][j][k] = 1 + sick[i - 1][j + 1][1 - k];
else sick[i][j][k] = sick[i][j + 1][k];
}
}
int scnt = 0;
int i = strlen(s) - 1, j = lo, em = 1 - m, togo = ans - i - 1;
int how = 0, fpos = lo, apos = lo;
if(ans % 2) togo--, j++, fpos++;
while(i >= 0 && j < n){
if(sick[i + 1][j][em] == togo){
char cur = '{';
int pos = 0;
while(sick[i + 1][j][em] == togo && j < n){
if(em == 0){
if(s[i] < a[j]){
if(a[j] < cur){
cur = a[j];
pos = j;
}
}
}
else{
if(s[i] > a[j]){
if(a[j] < cur){
cur = a[j];
pos = j;
}
}
}
j++;
}
shalf[scnt++] = cur;
j = pos + 1;
how++;
if(how == 1) fpos = j - 1;
togo--;
em = 1 - em;
i--;
}
else j++;
}
shalf[scnt] = '';
int mcnt = 0;
if(ans % 2){
char cur = '{';
for(q = apos; q < fpos; q++){
if(a[q] < cur) cur = a[q];
}
mhalf[mcnt++] = cur;
}
mhalf[mcnt] = '';
printf("%s%s%s ", half, mhalf, shalf);
}
}
}
In C++
#include <cstdio>
#include<iostream>
#include <cstring>
#include <queue>
#include<vector>
#include <algorithm>
#include <limits>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define x first
#define y second
#define ll long long
#define mod 1000000007
#define N 2050
int dp[N][N][2],last[26],pre[N][26],next[N][26],lo[N],hi[N];
char s[N],ans[N];
int main()
{
int T,i,j,ca=0,n,k,p;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
n=strlen(s);
memset(last,-1,sizeof(last));
for(i=0;i<n;i++)
{
dp[i][i][0]=dp[i][i][1]=1;
last[s[i]-'a']=i;
for(j=0;j<26;j++)pre[i][j]=last[j];
}
memset(last,-1,sizeof(last));
for(i=n-1;i>=0;i--)
{
last[s[i]-'a']=i;
for(j=0;j<26;j++)next[i][j]=last[j];
}
for(k=2;k<=n;k++)
for(i=0;i+k-1<n;i++)
{
j=i+k-1;
dp[i][j][0]=max(dp[i+1][j][0],dp[i][j-1][0]);
dp[i][j][1]=max(dp[i+1][j][1],dp[i][j-1][1]);
if(s[i]<s[j])
dp[i][j][0]=max(dp[i][j][0],2+dp[i+1][j-1][1]);
if(s[i]>s[j])
dp[i][j][1]=max(dp[i][j][1],2+dp[i+1][j-1][0]);
}
int best=dp[0][n-1][0];
int a=0,b=n-1;
for(p=0,i=0;i<best/2;i++,p^=1)
{
lo[i]=a,hi[i]=b;
int now=dp[a][b][p];
for(j=0;j<26;j++)
{
int x=next[a][j];
if(x<0||x>b)continue;
int y=-1,yy=-1;
for(k=1;k<=25;k++)
{
if((p&&j-k<0)||(!p&&j+k>25))break;
if(p)yy=pre[b][j-k];else yy=pre[b][j+k];
if(yy<x+1||dp[x+1][yy-1][p^1]!=now-2)continue;
y=max(y,yy);
}
if(y<0)continue;
ans[i]=j+'a';
a=x+1,b=y-1;
break;
}
}
if(best%2)
{
for(j=0;j<26;j++)
{
int x=next[a][j];
if(x<0||x>b)continue;
a=x+1;
ans[i++]=j+'a';
break;
}
}
for(p^=1,b=a;i<best;p^=1,i++)
{
int ii=best-i-1,d=ans[ii]-'a';
int aa=lo[ii],bb=hi[ii],now=dp[aa][bb][p];
for(j=0;j<26;j++)
{
int y=next[b][j];
if(y<aa||y>bb)continue;
if((p&&d<=j)||(!p&&d>=j)||dp[aa][y][p]!=now)continue;
b=y+1;
ans[i]=j+'a';
break;
}
}
ans[i]=0;
puts(ans);
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.