USACO 3.1 contact

简单题、

但如果用什么trie树 AC自动机貌似很复杂  不去想了、

有要研究的去Nocow上

算法是:

从头到尾扫一遍,记hash[i,j]表示字符转化为二进制数i ,长度为j位  有多少个这样的字符 哈希表、

比如"0010"出现了3次 那么hash[2,4]就等于3

因为最大2^12,*上2^5  并不大、

扫描整个哈希表,保存在g数组中

g[i,1] 记录出现频数 ,g[i,2]记录字符长度 ,g[i,3]记录转化为二进制数是多少

举个例子吧: 比如字符串"001011“在整个字符串中出现了24次

                                长度为6 所以g[i,2]=6

                                二进制数为11所以g[i,3]=11

                                频数   g[i,1]=24

快排 这里有三个关键字  按照第一第二第三关键字 排序

迎刃而解、、

这段代码很重要

 
  
x: = g[(l + r) div 2 , 1 ];
p:
= g[(l + r) div 2 , 2 ];
q:
= g[(l + r) div 2 , 3 ];
repeat
while (g[i, 1 ] > x)or((g[i, 1 ] = x)and(g[i, 2 ] < p))or((g[i, 1 ] = x)and(g[i, 2 ] = p)and(g[i, 3 ] < q)) do
inc(i);
while (x > g[j, 1 ])or((x = g[j, 1 ])and(p < g[j, 2 ]))or((g[j, 1 ] = x)and(p = g[j, 2 ])and(q < g[j, 3 ])) do
dec(j);
if not(i > j) then
begin
y:
= g[i];
g[i]:
= g[j];
g[j]:
= y;
inc(i);
j:
= j - 1 ;
end;

有看不懂的……

程序:

{
ID: xiaweiy1
PROG: contact
LANG: PASCAL
}
const two:array[0..14]of longint=(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384);
      maxn=300000;
type rec=array[1..3]of longint;
var a,b,n,tot,i,j,k,t,done,tmp,total,now:longint;
    hash:array[0..4097,1..13]of longint;
    f:array[1..maxn]of char;
    s:string;
    g:array[1..maxn]of rec;
    tt:char;
function calc(st,en:longint):longint;
var sum,i,res:longint;
begin
sum:=-1;
res:=0;
for i:=en downto st do
    begin
    inc(sum);
    res:=res+two[sum]*(ord(f[i])-ord('0'));
    end;
exit(res);
end;
procedure sort(l,r: longint);
      var
         i,j,x,p,q: longint;
         y:rec;
      begin
         i:=l;
         j:=r;
         x:=g[(l+r) div 2,1];
         p:=g[(l+r) div 2,2];
         q:=g[(l+r) div 2,3];
         repeat
           while (g[i,1]>x)or((g[i,1]=x)and(g[i,2]<p))or((g[i,1]=x)and(g[i,2]=p)and(g[i,3]<q)) do
            inc(i);
           while (x>g[j,1])or((x=g[j,1])and(p<g[j,2]))or((g[j,1]=x)and(p=g[j,2])and(q<g[j,3])) do
            dec(j);
           if not(i>j) then
             begin
                y:=g[i];
                g[i]:=g[j];
                g[j]:=y;
                inc(i);
                j:=j-1;
             end;
         until i>j;
         if l<j then
           sort(l,j);
         if i<r then
           sort(i,r);
      end;
function getit(len,x:longint):string;
var t,p,i:longint;
    s:string;
begin
s:='';
p:=x;
while p>1 do
 begin
 t:=p mod 2;
 s:=char(t+48)+s;
 p:=p div 2;
 end;
if p=1 then s:='1'+s;
for i:=1 to len-length(s) do s:='0'+s;
exit(s);
end;
begin
assign(input,'contact.in');
reset(input);
assign(output,'contact.out');
rewrite(output);
readln(a,b,n);
while not eof do
  begin
  read(tt);
  if (ord(tt)=48)or(ord(tt)=49) then
     begin
     inc(tot);
     f[tot]:=tt;
     end;
  end;
for i:=1 to tot+1-a do
    begin
    for j:=a to b do
        begin
        t:=i+j-1;
        if t<=tot then
           begin
           tmp:=calc(i,t);
           inc(hash[tmp,j]);
           end;
        end;
    end;
total:=0;
for i:=0 to two[b] do
    begin
    for j:=a to b do
        begin
        if hash[i,j]<>0 then
           begin
           inc(total);
           g[total,1]:=hash[i,j];  //frequency
           g[total,2]:=j;          //length
           g[total,3]:=i;          //number
           end;
        end;
    end;
sort(1,total);
done:=0;
i:=1;
while i<=total do
  begin
  tmp:=g[i,1];
  j:=i;
  while (j+1<=total)and(g[j+1,1]=tmp)do inc(j);
  writeln(tmp);
  now:=0;
  for k:=i to j do
      begin
      inc(now);
      s:=getit(g[k,2],g[k,3]);
      if now mod 6=0 then
         begin
         write(s);
         if k<>j then writeln;
         end
      else
         begin
         if k<>j then write(s,' ') else write(s);
         end;
      end;
  writeln;
  inc(done);
  if done=n then break;
  i:=j+1;
  end;
close(input);
close(output);
end.

转载于:https://www.cnblogs.com/strawberryfou/archive/2011/02/14/1954247.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值