Contact (contact)[USACO 3.1.4]

算法:枚举

分析:其实是对统计数字的一个强化版本,由原先的统计数字改成了字符串,而且还需要枚举一下,给所有出现过的字符串快排,之后再进行比较一遍即可AC!

思考:USACO的数据神马的最坑爹了~

{

ID:1011mashuo

PROG:contact

LANG:PASCAL

}



program contact;



const

 maxn=100000;

 maxlen=12;

 maxm=4095;



type

 atp=record

  time,st:longint;

  nam:string[12];

 end;



var

 a,b,n,len:longint;

 f:array [0..maxlen,0..maxm] of atp;

 act:array [0..maxn] of atp;

 s:ansistring;



procedure init;

var

 ss:ansistring;

begin

 len:=0;

 s:='';

 readln(a,b,n);

 while not eof do

  begin

   readln(ss);

   s:=s+ss;

  end;

end;



function change(x:ansistring):longint;

var

 i:longint;

begin

 change:=0;

 for i:=1 to length(x) do inc(change,(ord(x[i])-48) shl (length(x)-i));

end;



function check1(x,y:ansistring):boolean;

begin

 if length(x)<length(y) then exit(true);

 if length(x)>length(y) then exit(false);

 if x<y then exit(true) else exit(false);

end;



function check2(x,y:ansistring):boolean;

begin

 if length(x)>length(y) then exit(true);

 if length(x)<length(y) then exit(false);

 if x>y then exit(true) else exit(false);

end;



procedure qsort(l,r:longint);

var

 i,j:longint;

 m,t:atp;

begin

 i:=l;

 j:=r;

 m:=act[(l+r) shr 1];

 repeat

  while (act[i].time>m.time) or ((act[i].time=m.time) and (check1(act[i].nam,m.nam))) do inc(i);

  while (act[j].time<m.time) or ((act[j].time=m.time) and (check2(act[j].nam,m.nam))) do dec(j);

  if i<=j then

   begin

    t:=act[i];

    act[i]:=act[j];

    act[j]:=t;

    inc(i);

    dec(j);

   end;

 until i>j;

 if i<r then qsort(i,r);

 if l<j then qsort(l,j);

end;



procedure main;

var

 i,j,m:longint;

 temp:ansistring;

begin

 for i:=a to length(s) do

  begin

   for j:=a to b do

    begin

     if i-j+1<1 then break;

     temp:=copy(s,i-j+1,j);

     m:=change(temp);

     f[j,m].nam:=temp;

     if f[j,m].time=0 then

      begin

       inc(len);

       f[j,m].st:=len;

       act[len]:=f[j,m];

      end;

     inc(f[j,m].time);

     inc(act[f[j,m].st].time);

    end;

  end;

 qsort(1,len);

end;



procedure print;

var

 j,k,top:longint;

begin

 k:=0;

 top:=0;

 j:=0;

 act[0].time:=maxlongint;

 while (k<=n) and (j<length(s)) do

  begin

   inc(j);

   if (act[j].time=0) then break;

   if (act[j].time=act[j-1].time) then

    begin

     if top=6 then

      begin

       writeln;

       write(act[j].nam);

       top:=1;

      end

     else

      begin

       write(' ',act[j].nam);

       inc(top);

      end;

    end

   else

    begin

     if k=n then break;

     if k<>0 then writeln;

     writeln(act[j].time);

     write(act[j].nam);

     inc(k);

     top:=1;

    end;

  end;

 writeln;

end;



begin

 assign(input,'contact.in'); reset(input);

 assign(output,'contact.out'); rewrite(output);



 init;

 main;

 print;



 close(input); close(output);

end.



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值