【USACO4-3-3】字母游戏Letter Game 枚举

题目

首先我们判断一下读入的字符串是否满足规则,满足就存入。

然后就是暴力枚举寻找最大值

先判断一个单词的情况,再判断能否组成两个单词以及两个单词的情况。

因为有很多非法的单词所以不会超时。

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值