Problem:
Problem D:
77377
At the risk of its future, International Cellular Phones Corporation (ICPC) invests its resources in developing new mobile phones, which are planned to be equipped with Web browser, mailer, instant messenger, and many other advanced communication tools. Unless members of ICPC can complete this stiff job, it will eventually lose its market share.
You are now requested to help ICPC to develop intriguing text input software for small mobile terminals. As you may know, most phones today have twelve buttons, namely, ten number buttons from "
0
" to "
9
" and two special buttons "
*
" and "
#
". Although the company is very ambitious, it has decided to follow today's standards and conventions. You should not change the standard button layout, and should also pay attention to the following standard button assignment.
button
letters
button
letters
2
a, b, c
6
m, n, o
3
d, e, f
7
p, q, r, s
4
g, h, i
8
t, u, v
5
j, k, l
9
w, x, y, z
This means that you can only use eight buttons for text input.
Most users of current ICPC phones are rushed enough to grudge wasting time on even a single button press. Your text input software should be economical of users' time so that a single button press is suffcient for each character input. In consequence, for instance, your program should accept a sequence of button presses "
77377
" and produce the word "
press
". Similarly, it should translate "
77377843288866
" into "press the button".
Ummm... It seems impossible to build such text input software since more than one English letter is represented by a digit!. For instance, "
77377
" may represent not only "press" but also any one of 768 (= 4 × 4 × 3 × 4 × 4) character strings. However, we have the good news that the new model of ICPC mobile phones has enough memory to keep a dictionary. You may be able to write a program that filters out
false words
, i.e., strings not listed in the dictionary.
Input
The input consists of multiple data sets, each of which represents a dictionary and a sequence of button presses in the following format.
n
word
1
.
.
.
word
n
sequence
n
in the first line is a positive integer, representing the number of words in the dictionary. The next
n
lines, each representing a word in the dictionary, only contain lower case letters from `
a
' to `
z
'. The order of words in the dictionary is arbitrary (not necessarily in the lexicographic order). No words occur more than once in the dictionary. The last line, sequence, is the sequence of button presses, and only contains digits from `
2
' to `
9
'.
You may assume that a dictionary has at most one hundred words and that the length of each word is between one and fifty, inclusive. You may also assume that the number of input digits in the
sequence
is between one and three hundred, inclusive.
A line containing a zero indicates the end of the input.
Output
For each data set, your program should print all sequences that can be represented by the input sequence of button presses. Each s
...(truncated)

Submitted solutions:

code_snippet: // start: 10:34
// stop: 10:43
// start: 10:50
// stop: 11:22
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cctype>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <sstream>
#include <deque>

#define REP(i, n) for ( int i = 0; i < n; i++ )

using namespace std;

map<char, vector<char> > table;
// map<string, int> close;

struct input {
    int idx;
    string str;
    string current;
    vector<string> words;
};

// なければ空文字列を返す？
bool in_dictionary(vector<string> &dict, string word) {
    REP(i, dict.size()) {
        if ( dict[i] == word ) {
            return true;
        }
    }
    return false;
}

bool dict_match(vector<string> &dict, string word) {
    REP(i, dict.size()) {
        int match = 0;
        REP(j, word.size()) {
            if(dict[i][j] == word[j]) match++;
            else break;
        }
        if(match == word.size()) {
            // cout << word << " match: " << dict[i] << endl;
            return true;
        }
    }
    // cout << word << " is not match." << endl;
    return false;
}

void dump(vector<string> &arr) {
    REP(i, arr.size()) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

string join(vector<string> &arr, string glue = " ") {
    string ret = arr[0];
    for(int i = 1; i < arr.size(); i++) {
        ret += glue + arr[i];
    }
    return ret;
}

vector<string> decode(vector<string> &dict, string line) {
    vector<string> ret(1);

    queue<input> inputs;
    struct input init = {0, "", "", vector<string>()};

    inputs.push(init);

    while(!inputs.empty()) {
        struct input inp = inputs.front(); inputs.pop();

        string key = inp.str + inp.current;
        // if(close[key]) continue;
        // close[key] = 1;

        if(inp.idx >= line.size() && inp.current == "") {
            ret.push_back(join(inp.words));
            // cout << "end of parse!!!!! " << ret.size() << endl;
            // dump(ret);
            // break;
        }

        REP(i, table[line[inp.idx]].size()) {
            string tmp_current = inp.current, tmp_str = inp.str;
            vector<string> tmp_words = inp.words;

            tmp_current += table[line[inp.idx]][i];
            tmp_str += table[line[inp.idx]][i];

            // cout << tmp_current << " in-dic:" << in_dictionary(dict, tmp_current) << endl;
            if(in_dictionary(dict, tmp_current)) {
                string match_current = tmp_current;
                vector<string> match_words = tmp_words;

                match_words.push_back(match_current);
                match_current = "";
                // cout << inp.idx+1 <<  " add dump: ";
                // dump(match_words);

                struct input match_inp = {inp.idx+1, tmp_str, match_current, match_words};
                inputs.push(match_inp);
            }

            // cout << tmp_current << " " << dict_match(dict, tmp_current) << endl;
            if(inp.idx <= line.size() && dict_match(dict, tmp_current)) {
                struct input new_inp = {inp.idx+1, tmp_str, tmp_current, tmp_words};
                inputs.push(new_inp);
            }
        }
    }

    return ret;
}

// vector<string> convert(input inp) {

// }

int main() {
    int n;
    table['2'] = vector<char>(3);
    table['3'] = vector<char>(3);
    table['4'] = vector<char>(3);
    table['5'] = vector<char>(3);
    table['6'] = vector<char>(3);
    table['7'] = vector<char>(4);
    table['8'] = vector<char>(3);
    table['9'] = vector<char>(4);

    table['2'][0] = 'a';
    table['2'][1] = 'b';
    table['2'][2] = 'c';
    table['3'][0] = 'd';
    table['3'][1] = 'e';
    table['3'][2] = 'f';
    table['4'][0] = 'g';
    table['4'][1] = 'h';
    table['4'][2] = 'i';
    table['5'][0] = 'j';
    table['5'][1] = 'k';
    table['5'][2] = 'l';
    table['6'][0] = 'm';
    table['6'][1] = 'n';
    table['6'][2] = 'o';
    table['7'][0] = 'p';
    table['7'][1] = 'q';
    table['7'][2] = 'r';
    table['7'][3] = 's';
    table['8'][0] = 't';
    table['8'][1] = 'u';
    table['8'][2] = 'v';
    table['9'][0] = 'w';
    table['9'][1] = 'x';
    table['9'][2] = 'y';
    table['9'][3] = 'z';

    while(cin >> n, n) {
        vector<string> dict(n);
        string line;

        // close.clear();

        REP(i, n) {
            cin >> dict[i];
        }

        cin >> line;

        vector<string> results = decode(dict, line);
        REP(i, results.size()) {
            if ( results[i] != "" ) cout << results[i] << "." << endl;
        }
        cout << "--" << endl;
    }   
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1308
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    int num[] = {3, 3, 3, 3, 3, 4, 3, 4};
    char x = 'a';
    vector<char> button(256);
    for(int i=0; i<8; ++i){
        for(int j=0; j<num[i]; ++j){
            button[x] = '2' + i;
            ++ x;
        }
    }

    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        map<string, vector<string> > dic;
        for(int i=0; i<n; ++i){
            string s;
            cin >> s;
            int m = s.size();
            string b(m, ' ');
            for(int i=0; i<m; ++i)
                b[i] = button[s[i]];
            dic[b].push_back(s);
        }

        string press;
        cin >> press;
        n = press.size();
        vector<vector<string> > ret(n+1);
        ret[0].push_back("");
        for(int i=0; i<n; ++i){
            for(int j=max(0, i-49); j<=i; ++j){
                string s = press.substr(j, i-j+1);
                map<string, vector<string> >::iterator it = dic.find(s);
                if(it != dic.end()){
                    for(unsigned k=0; k<ret[j].size(); ++k){
                        for(unsigned l=0; l<it->second.size(); ++l){
                            ret[i+1].push_back(ret[j][k] + it->second[l] + ' ');
                        }
                    }
                }
            }
        }

        for(unsigned k=0; k<ret[n].size(); ++k){
            ret[n][k][ret[n][k].size()-1] = '.';
            cout << ret[n][k] << endl;
        }
        cout << "--" << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <map>
#include <string>
using namespace std;

const string ButtonTable = "22233344455566677778889999";

string hash(const string& s)
{
  string t = "";
  for (unsigned int i = 0; i < s.size(); ++i)
    t += ButtonTable[s[i] - 'a'];
  return t;
}

void solve(multimap<string, string>& dic, string seq, string ans)
{
  for (unsigned int i = 1; i <= seq.size(); ++i) {
    string h = seq.substr(0, i), rem = seq.substr(i);
    for (multimap<string, string>::iterator it = dic.find(h); it != dic.end() && (*it).first == h; ++it) {
      if (rem.empty()) 
	cout << ans << (*it).second << "." << endl;
      else
	solve(dic, rem, ans + (*it).second + " ");
    }
  }
  return;
}

int main()
{
  int n;
  while (cin >> n) {
    if (n == 0)
      break;

    multimap<string, string> dic;
    for (int i = 0; i < n; ++i) {
      string s;
      cin >> s;
      dic.insert(multimap<string, string>::value_type(hash(s), s));
    }

    string seq;
    cin >> seq;
    solve(dic, seq, "");

    cout << "--" << endl;

  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <map>
#include <queue>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

struct NODE{
	string now;
	vector<string> words;
};

int main(){
	int table[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
	int n;
	while(cin >> n ,n ){
		vector< pair<string,string> > data;
		string s;
		set< vector<string> > ret;
		for(int i=0;i<n;i++){
			cin >> s;
			string tmp = s;
			for(int j=0;j<s.length();j++){
				s[j] = table[s[j]-'a']+'0';
			}
			data.push_back( make_pair(tmp,s) );
		}
		string hoge;
		cin >> hoge;
		
		queue<NODE> Q;
		NODE t;
		Q.push(t);
		
		//set<string> done;
		
		while(Q.size()){
			NODE q = Q.front();Q.pop();
			//cout << q.now << endl;
			if( q.now == hoge){
				ret.insert(q.words);
			}
			
			for(int i=0;i<data.size();i++){
				NODE next = {q.now + data[i].second,q.words};
				next.words.push_back(data[i].first);
				if( hoge.find(next.now) != 0)continue;
				//if( done.find(next.now) != done.end() )continue;
				//done.insert(next.now);
				Q.push(next);
			}
		}
		//sort(ret.begin(),ret.end(),greater<string>());
		for( set<vector<string> >::iterator it = ret.begin(); it != ret.end(); ++it){
			for(int i=0; i<(*it).size();i++)
				cout << (*it)[i] << (i == (*it).size()-1?".\n":" ");
		}
		cout << "--" << endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 944
final_rank: 4