首先我们判断一下读入的字符串是否满足规则,满足就存入。
然后就是暴力枚举寻找最大值
先判断一个单词的情况,再判断能否组成两个单词以及两个单词的情况。
因为有很多非法的单词所以不会超时。
#include<iostream>
#include<map>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define inf 0x3f3f3f3f
#define N 400001
#define ll long long
using namespace std;
struct word{int len,d;char ch[10];}w[N];
struct node{int x,y;}res[N];
map<char,int>mp;
char s[8];
int flag[30],dc[27]={2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7};
int mx=-1,tot,cnt;
bool judge1()//判断当前读入的字符串是否合法
{
int cur[30];memset(cur,0,sizeof(cur));
for (int i=0;i<strlen(s);i++)
{
int x=s[i]-'a';cur[x]++;
if (cur[x]>flag[x]) return false;
}
return true;
}
bool judge2(int x,int y)
{
int cur[30];
memset(cur,0,sizeof(cur));
for (int i=0;i<w[x].len;i++)
{
int p=w[x].ch[i]-'a';cur[p]++;
if (cur[p]>flag[p]) return false;
}
for (int j=0;j<w[y].len;j++)
{
int q=w[y].ch[j]-'a';cur[q]++;
if (cur[q]>flag[q]) return false;
}
return true;
}
int main()
{
scanf("%s",s);
for (int i=0;i<strlen(s);i++){int x=s[i]-'a';flag[x]++;}
while(scanf("%s",s))
{
if (s[0]=='.') break;
if (judge1())//如果合法
{
w[++tot].len=strlen(s);
for (int i=0;i<strlen(s);i++)
w[tot].ch[i]=s[i],w[tot].d+=dc[s[i]-'a'];
}
}
for (int i=1;i<=tot;i++)
{
if (w[i].d==mx)res[++cnt].x=i;
if (w[i].d>mx)
{
mx=w[i].d;
cnt=0;
res[++cnt].x=i;
}
for (int j=i;j<=tot;j++)
{
if (judge2(i,j))
{
if (w[i].d+w[j].d==mx){res[++cnt].x=i;res[cnt].y=j;}
if (w[i].d+w[j].d>mx)
{
mx=w[i].d+w[j].d;
cnt=0;
res[++cnt].x=i;res[cnt].y=j;
}
}
}
}
printf("%d\n",mx);
for (int i=1;i<=cnt;i++)
{
for (int j=0;j<w[res[i].x].len;j++) printf("%c",w[res[i].x].ch[j]);
if (res[i].y)
{
printf(" ");
for (int j=0;j<w[res[i].y].len;j++) printf("%c",w[res[i].y].ch[j]);
}
printf("\n");
}
return 0;
}