5.14特长生模拟 门票


题目

mxy 正要经过新世界的大门。
现在有很多人在门口排队,每个人将会被发到一个有效的通行密码作为门票。一个有
效的密码由L(3 <= L <= 15)个小写字母(‘a’…‘z’)组成,至少有一个元音(‘a’, ‘e’, ‘i’,
‘o’ 或 ‘u’)和两个辅音(除去元音以外的音节),并且是按字母表顺序出现的(例如,‘abc’
是有效的,而’bac’不是) 。
mxy 想要知道今天的有效密码是什么。
现在给定一个期望长度L 和C(1 <= C <= 26)个小写字母,写一个程序,输出所有的
长度为L、能由这给定的C 个字母组成的有效密码。密码必须按字母表顺序打印出来,一行
一个。
【输入】
输入数据共2 行。
第1 行: 两个由空格分开的整数,L 和C。(3 <= L <= 15,1 <= C <= 26)
第2 行: C 个由1 个空格隔开的小写字母,密码是由这个字母集中的字母来构建的。
【输出】
若干行,每行输出一个长度为L 个字符的密码(没有空格)。输出行必须按照字母顺序
排列。你的程序只需输出前25000 个有效密码,即使后面还存在有效密码。

题解

暴搜,暴搜,要剪枝
1.剩下的元音不够了
2.剩下的辅音不够了
3.已经有25000个密码了
可以预处理剩下元音和辅音的数量
时间复杂度O(25000*26)
代码

var
  a:array[0..27]of char;
  y,f:array[0..26]of longint;
  l,c,i,j,m:longint;
  s:string;

function yuan(a:char):boolean;
begin
  if (a='a')or(a='e')or(a='i')or(a='o')or(a='u') then exit(true);
  exit(false);
end;

procedure dfs(e,t,k,j:longint;s:string);
var
  i:longint;
begin
  if (k=l)and(e>0)and(t>1) then
    begin if m>=25000 then halt;writeln(s);inc(m);exit;end;
  if (e=0)and(y[j]=0) then exit;
  if 2-t>f[j] then exit;
  for i:=j to c do
    if yuan(a[i]) then dfs(e+1,t,k+1,i+1,s+a[i])
                  else dfs(e,t+1,k+1,i+1,s+a[i]);
end;

begin
  assign(input,'ticket.in');
  assign(output,'ticket.out');
  reset(input);rewrite(output);
  readln(l,c);
  for i:=1 to c do
    read(a[i],a[0]);
  for i:=1 to c-1 do
    for j:=i+1 to c do
      if a[i]>a[j] then
        begin
          a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
        end;
  for i:=c downto 1 do
    begin
      y[i]:=y[i+1];f[i]:=f[i+1];
      if yuan(a[i]) then inc(y[i]) else inc(f[i]);
    end;
  dfs(0,0,0,1,s);
  close(input);close(output);
end.

二十年来辨是非,榴花开处照宫闱。三春争及初春景,虎兕(兔)相逢大梦归。——《红楼梦》·十二金钗判词·贾元春

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值