cti:char to int 类型转换
itcn:int to char(turn into number) 整型数转化为字符数字
getstr(x,l,r) :取x在 [l,r] 间的子串
print :递归打印答案(因为先打印左侧,在打印右侧,所以顺序正确)
password :待翻译的密码;
dpi,j :password的子段[i,j]是否可以翻译
ans_i,j:(在dpi,j==true的情况下)字段[i,j]的翻译答案的一种可能的表示方式(即打断点的方式)
注:若 ans_i,j==−1 ,则表示子段 [i,j] 不需要打断即可翻译
word(map<string,bool>) :word[x(string)] :表示字符串x(数字串)是否存在至少一种直接翻译(即不打断)的方式。
getwor(map<string,string>):getworx(string):表示字符串x(数字串)的一个对应的单词。
dp原则:区间dp,如果区间可以整个翻译,就记ans_i,j=−1,如果不行,就枚举断点mid,直到找出一个可行的断开的方案,更新dpi,j=true,并记录ans_i,j=mid。 最后依照ans_0,length−1递归输出。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <cstring>
using namespace std;
bool dp[105][105];
int ans_[105][105];
map<string,bool> word;
map<string , string > getwor;
string password;
int cti(char c)
{
if('a' <= c && c <= 'c') return 1;
if(c <= 'f') return 2;
if(c <= 'i') return 3;
if(c <= 'l') return 4;
if(c <= 'n') return 5;
if(c <= 'q') return 6;
if(c <= 't') return 7;
if(c <= 'w') return 8;
if(c <= 'z') return 9;
return -1;
}
char itcn(int num)
{
return (char)(num + 48);
}
inline string getstr(string x,int l,int r)
{
string res;
for(int i = l;i<=r;++i)
{
res += x[i];
}
return res;
}
bool flag = false;
void print(int l,int r)
{
if(ans_[l][r] == -1)
{
if(flag) cout<<" ";
flag = true;
cout<<getwor[getstr(password,l,r)];
}
else
{
print(l,ans_[l][r]);
print(ans_[l][r]+1,r);
}
return ;
}
int main()
{
memset(dp,0,sizeof(dp));
memset(ans_,0,sizeof(ans_));
int n;
scanf("%d",&n);
// string password;
getchar();
getline(cin,password);
int length = password.length();
for(int i=1;i<=n;++i)
{
string worder,old_;
getline(cin,worder);
int len = worder.length();
old_ = worder;
for(int i=0;i<len;++i)
{
worder[i] = itcn(cti(worder[i]));
}
word[worder] = true;
getwor[worder] = old_;
}
// sum[0] = password[0];
// for(int i=1;i<length;++i)
// {
// char c = password[i];
// sum[i] = sum[i-1] + c;
// }
for(int len = 1;len <= length;++len)
{
for(int i=0,j=i+len - 1;j < length;++i,++j)
{
if(word[getstr(password,i,j)] == true)
{
dp[i][j] = true;
ans_[i][j] = -1;
continue;
}
for(int mid = i;mid < j;++mid)
{
if(dp[i][mid] && dp[mid+1][j])
{
dp[i][j] = true;
ans_[i][j] = mid;
break;
}
}
}
}
if(!dp[0][length-1]) printf("No Solutions!");
else print(0,length-1);
// printf("%d",dp[0][length-2]);
return 0;
}