USACO/contact

这题难得有感觉,于是就把思路写下来。
因为串只有0和1,所以可以转为二进制来做。
因为有前导0,所以要记录位数。
每读入一位就做一次,而t数组是用来控制长度的。
于是程序如下:

{
ID:smdcnne1
PROG:contact
LANG:PASCAL
}
type _ans=record
x:longint;
s:string;
end;
var tot,i,j,k,l,m,a,b,n,g,last,p:longint;
st:ansistring; ch:char;
x:array[1..12]of longint;
f:array[1..12,0..10000]of longint;
t:array[1..12]of integer;
ans:array[0..50000]of _ans;
procedure qsort(l,r:longint);
var i,j:longint;x:_ans;
begin
i:=l;j:=r;x:=ans[(l+r)shr 1];
repeat
while (ans[i].x>x.x)or
((ans[i].x=x.x)and(length(ans[i].s)length(x.s)))or
((ans[j].x=x.x)and(length(ans[j].s)=length(x.s))and(ans[j].s>x.s))
do dec(j);
if i< =j then begin ans[0]:=ans[i];ans[i]:=ans[j];ans[j]:=ans[0]; inc(i);dec(j); end; until i>=j;
if il then qsort(l,j);
end;
begin
assign(input,'contact.in');
assign(output,'contact.out');
reset(input);rewrite(output);
readln(a,b,n);
st:='';
for i:=a to b do t[i]:=(1 shl (i-1))-1;
read(ch); l:=0;
repeat
if ch in ['0'..'1'] then begin
inc(l);
for i:=a to b do
begin
x[i]:=x[i] and t[i];
x[i]:=x[i]*2+ord(ch)-ord('0');
if l>=i then inc(f[i,x[i]]);
end; end;
read(ch);
until eof;
tot:=0;
for i:=a to b do
begin
for j:=0 to (1 shl i)-1 do
begin
if f[i,j]>0 then
begin
inc(tot);
ans[tot].s:='';
ans[tot].x:=f[i,j];
g:=j;
for k:=1 to i do
begin
if (g and 1)>0 then ans[tot].s:='1'+ans[tot].s else ans[tot].s:='0'+ans[tot].s;
g:=g shr 1;
end;
end;
end;
end;
qsort(1,tot);
i:=1;
repeat
if ans[i].x<>last then
begin
dec(n);
if n>=0 then begin if i>1 then writeln; writeln(ans[i].x);
write(ans[i].s);
last:=ans[i].x; p:=1; end;
end else begin
inc(p);
if p mod 6=1 then begin writeln;write(ans[i].s)end else
write(' ',ans[i].s);
end;
inc(i);
until (n<0)or(i>tot);
writeln;
close(input);close(output);
end.

《USACO/contact》上有3条评论

    1. 只是WordPress不好弄空格罢了。。
      – – 就算别人写的程序没缩进,我拿来不重新整一下缩进就根本不想看

回复 smdcn 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注