mahmoud-a
9/1/2017 - 11:50 AM

https://arena.topcoder.com/#/u/practiceCode/1259/1260/1331/1/1259

#include <bits/stdc++.h>

#define ll long long
#define sz(v) ((int) ((v).size()))
#define clr(v, d) memset(v, d, sizeof(v))
#define lp(i, n) for(int i = 0; i < (int)(n); ++i)
#define rep(i, v) for(int i = 0; i < sz(v); ++i)

using namespace std;

const int MAX = 55;
const int OO = 1e9;

int n, l;
string a[MAX];
string s;
int cache[MAX][MAX];

bool isValid(int st, int en) {
    string sub = s.substr(st, en-st+1);
    lp(i, n) {
        if(a[i] == sub) {
            //cout << "DEBUG sub: " << sub << endl;
            return 1;
        }

    }

    return 0;
}

int minDeco(int i, int last) {
    if(i==l)
        if(i == last)
            return 1;
        else
            return OO;
    int &ret = cache[i][last];
    if(ret != -1)
        return ret;
    ret = 0;
    int tmp;
    if(isValid(last, i)) {
        tmp = minDeco(i+1, i+1);
        if(tmp != OO)
            ret += tmp;
    }

    tmp = minDeco(i+1, last);
    if(tmp != OO)
        ret += tmp;
    if(ret == 0)
        ret = OO;
    return ret;
}

string output = "";
void traceOperations(int i, int last) {
    if(i == l)
        return;

    int ch1 = -5;
    if(isValid(last, i)) {
        ch1 = minDeco(i+1, i+1);
    }

    int opt = minDeco(i, last);
    if(opt == ch1) {
        if(last == 0)
            output += s.substr(last, i-last+1);
        else
            output += (" " + s.substr(last, i-last+1));
        traceOperations(i+1, i+1);
    } else {
        traceOperations(i+1, last);
    }
    return;

}

/*

int main() {
    clr(cache, -1);
    cin>>n;

    lp(i, n) {
        cin>>a[i];
    }
    cin>>s;
    l = s.length();

    int x = minDeco(0, 0);
    if(x != 1)
        cout << (x >= OO ? "IMPOSSIBLE!" : "AMBIGUOUS!") << endl;
    else {
        traceOperations(0, 0);
        cout << output << endl;
    }

    return 0;
}*/


class MessageMess  {
public:
    string restore(vector<string> v, string s1) {
        clr(cache, -1);
        s = s1;
        l = s.length();
        n = v.size();
        lp(i, n) {
            a[i] = v[i];
        }
        int x = minDeco(0, 0);
        if(x != 1)
            return (x >= OO ? "IMPOSSIBLE!" : "AMBIGUOUS!");
        else {
            traceOperations(0, 0);
            return output;
        }
    }
};