Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 2456 | Accepted: 852 | Special Judge |
Description
1 ij 2 abc 3 def
4 gh 5 kl 6 mn
7 prs 8 tuv 9 wxy
0 oqz
Input
Output
Sample Input
7325189087 5 it your reality real our
Sample Output
reality our
Source
/* DP,类似矩阵链乘法,dps[i][j].minNum表示输入电话串中第i位至第j位子串需要的最少单词数, 则dps[i][j].minNum = min(dps[i][j].minNum, dps[i][k].minNum + dps[k + 1][j].minNum), i <= k < j dps[i][j].curPos记录这个最优的k 首先要做的是边输入单词边处理,对每一个单词在电话号码串中寻找匹配串,加入对于单词str在号码串中找 到匹配的字串str(i, j)则将dps[i][j].minNum 设置为1,dps[i][j].str = str */ #include <iostream> #include <string> #define minv(a, b) ((a) <= (b) ? (a) : (b)) #define maxv(a, b) ((a) >= (b) ? (a) : (b)) #define MAX_N 105 #define MAX_VAL 1000000 using namespace std; struct dp { int minNum; int cutPos; string str; }dps[MAX_N + 1][MAX_N + 1]; int len, wordNum, minLen; char map[26] = {'2', '2', '2', '3', '3', '3', '4', '4', '1', '1', '5', '5', '6', '6', '0', '7', '0', '7', '7', '8', '8', '8', '9', '9', '9', '0'}; string phone; void init() { int i, j; for(i = 0; i < len; i++) { for(j = 0; j < len; j++) { dps[i][j].minNum = MAX_VAL; dps[i][j].str = ""; dps[i][j].cutPos = -1; } } minLen = MAX_VAL; } //将字母单词word转化为数字序列digits void getDigits(const string &word, string &digits) { int len = word.length(); digits = word; for(int i = 0; i < len; i++) digits[i] = map[word[i] - 'a']; } void dp() { int l, f, t, k; //遍历长度 for(l = minLen; l <= len; l++) { //遍历起始处 for(f = 0; f <= len - l; f++) { t = f + l - 1; int curMinLen = MAX_VAL; int curMinPos = 0; //遍历中间拆分位置 for(k = f; k < t; k++) { if(curMinLen > dps[f][k].minNum + dps[k + 1][t].minNum) { curMinLen = dps[f][k].minNum + dps[k + 1][t].minNum; curMinPos = k; } } if(dps[f][t].minNum > curMinLen) { dps[f][t].minNum = curMinLen; dps[f][t].cutPos = curMinPos; } } } } //递归打印结果 void printRes(int s, int t) { if(dps[s][t].cutPos == -1) cout<<dps[s][t].str<<" "; else { printRes(s, dps[s][t].cutPos); printRes(dps[s][t].cutPos + 1, t); } } int main() { int i, f, t; string word; string digits; cin>>phone; len = phone.length(); init(); cin>>wordNum; for(i = 1; i <= wordNum; i++) { cin>>word; int wordLen = word.length(); if(wordLen < minLen) minLen = wordLen; getDigits(word, digits); for(f = 0; f <= len - wordLen; f++) { t = f + wordLen - 1; if(dps[f][t].minNum != MAX_VAL) continue; if(phone.substr(f, wordLen) == digits) { dps[f][t].minNum = 1; dps[f][t].str = word; } } } dp(); if(dps[0][len - 1].minNum == MAX_VAL) cout<<"No solution."<<endl; else { printRes(0, len - 1); printf("/n"); } return 0; }