谷仓的安保

谷仓的安保

题目

Farmer John给谷仓安装了一个新的安全系统,并且要给牛群中的每一个奶牛分配一个有效的密码。
一个有效的密码由L(3 <= L <= 15)个小写字母(来自传统的拉丁字母集’a’…‘z’)组成,
至少有一个元音(‘a’, ‘e’, ‘i’, ‘o’, 或 ‘u’)和两个辅音(除去元音以外的音节),
并且是按字母表顺序出现的(例如,'abc’是有效的,而’bac’不是) 。

给定一个期望长度L和C个小写字母,写一个程序,打印出所有的长度为L、能由这给定的C个字母组成的有效密码。
密码  必须按字母表顺序打印出来,一行一个。
你的程序只需输出前25,000个有效密码,即使后面还存在有效密码。

输入

第一行: 两个由空格分开的整数,L和C;

第二行: C个空格分开的小写字母,密码是由这个字母集中的字母来构建的。

输出

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

输入样例

4 6
a t c i s w

输出样例

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

题解

题意是从c个字母中选出L个字母组成至少有两个辅音与一个元音的组合,并按序输出。
由于输入不一定有序,而输出要求有序,所以先对输入的字母排序。
然后dfs找出所有组合,最后判断是否符合两辅一元的规定并输出。

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
unsigned long long n,a[1000],b[1000],m,e,c[1000],f,ans=0; 
char d[1000];
void dfs(int dep,int j){ //搜索,j用来记录上个字母,本次从j开始搜索就能避免重复
	if(dep>n){
		if(e>=1&&f>1){
			ans++;
			for(int i=1;i<=n;i++){
				printf("%c",(char)b[i]); //转化为字符输出
			}if(ans>=25000){
				exit(0);//结束程序
			}cout<<endl;
		}
	}else{
		for(int i=j;i<=m;i++){
			if(c[i]==0){ //排除出现过的字母
				if((char)a[i]=='a'||(char)a[i]=='e'||(char)a[i]=='i'||(char)a[i]=='o'||(char)a[i]=='u'){
					e++; //记录元音
				}else{
					f++; //记录辅音
				}
				c[i]=1;
				b[dep]=a[i];
				dfs(dep+1,i);
				c[i]=0;
				if((char)a[i]=='a'||(char)a[i]=='e'||(char)a[i]=='i'||(char)a[i]=='o'||(char)a[i]=='u'){
					e--;
				}else{
					f--;
				}
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%s",&d[i]);
	}sort(d+1,d+1+m); //排序
	for(int i=1;i<=m;i++){
		a[i]=d[i];
	}
	dfs(1,1);
}

猜你喜欢

转载自blog.csdn.net/keyixi/article/details/108072244
今日推荐