SSLOJ·谷仓的安保【DFS】

SSLOJ 1374 谷仓的安保

    • Description--
    • Input--
    • Output--
    • Sample Input--
    • Sample Output--
    • 说明--
    • 解题思路--
    • 代码--

Description–

Farmer John给谷仓安装了一个新的安全系统,并且要给牛群中的每一个奶牛分配一个有效的密码。一个有效的密码由L个小写字母(来自传统的拉丁字母集’a’…‘z’)组成,至少有一个元音(‘a’, ‘e’, ‘i’, ‘o’, 或 ‘u’)和两个辅音(除去元音以外的音节),并且是按字母表顺序出现的(例如,'abc’是有效的,而’bac’不是) 。
给定一个期望长度L和C个小写字母,写一个程序,打印出所有的长度为L、能由这给定的C个字母组成的有效密码。密码必须按字母表顺序打印出来,一行一个。
你的程序只需输出前25,000个有效密码,即使后面还存在有效密码。


Input–

第一行: 两个由空格分开的整数,L和C;
第二行: C个空格分开的小写字母,密码是由这个字母集中的字母来构建的。

Output–

第一至?行: 每一个输出行包括一个长度为L个字符的密码(没有空格)。输出
行必须按照字母顺序排列。如果存在多于25,000个有效密码,你的程序必须在输出25,000个有效密码后停止。


Sample Input–

4 6
a t c i s w

Sample Output–

acis
acit
aciw
acst
acsw
actw
aist
aisw
aitw
astw
cist
cisw
citw
istw


说明–

3 <= L <= 15


解题思路–

把字母从小到大排序 --> dfs枚举组成的字符串 --> 判断 + 输出


代码–

#include 
#include 
#include 
#include 

using namespace std;

int l, c, t, d[30];
bool p[30], pd[30];
char a;

bool check(string ss)
{
	int o = 0, g = 0;
	for (int i = 0; i < (int)ss.size(); ++i)
	  if (ss[i] == 'a' || ss[i] == 'e' || ss[i] == 'i' || ss[i] == 'o' || ss[i] == 'u') o++;
	  else g++;
	if (o >= 1 && g >= 2) return 1;
	return 0;
}

void cfy(int lev, string s, int be)
{
	if (lev > l)
	{
		if (check(s)) t++, cout << s << endl;
		if (t >= 25000) exit(0);
		return ;
	}
	for (int i = be; i <= c; ++i)
	  if (!pd[i])
	  {
	  	  pd[i] = 1;
	  	  cfy(lev + 1, s + char(d[i] + 96), i + 1);
	  	  pd[i] = 0;
	  }
}

int main()
{
	scanf("%d%d", &l, &c);
	for (int i = 1; i <= c; ++i)
	  cin >> a, p[int(a - 96)] = 1;
	for (int i = 1; i <= 26; ++i)
	  if (p[i]) d[++t] = i; //这是一个垃圾的排序
	t = 0;
	cfy(1, "", 1);
	
	return 0;
} 

你可能感兴趣的:(搜索)