【NOIP2013模擬】太鼓達人
阿新 • • 發佈:2018-12-31
題目描述
七夕祭上,Vani牽著cl的手,在明亮的燈光和歡樂的氣氛中愉快地穿行。這時,在前面忽然出現了一臺太鼓達人機臺,而在機臺前坐著的是剛剛被精英隊伍成員XLk、Poet_shy和lydrainbowcat拯救出來的的applepi。看到兩人對太鼓達人產生了興趣,applepi果斷閃人,於是cl拿起鼓棒準備挑戰。然而即使是在普通難度下,cl的路人本性也充分地暴露了出來。一曲終了,不但沒有過關,就連鼓都不靈了。Vani十分過意不去,決定幫助工作人員修鼓。
鼓的主要元件是M個圍成一圈的感測器。每個感測器都有開和關兩種工作狀態,分別用1和0表示。顯然,從不同的位置出發沿順時針方向連續檢查K個感測器可以得到M個長度為K的01串。Vani知道這M個01串應該是互不相同的。而且鼓的設計很精密,M會取到可能的最大值。現在Vani已經瞭解到了K的值,他希望你求出M的值,並給出字典序最小的感測器排布方案。
思路
我們可以先將所有的01串按字典序從小到大做出來。我們很容易發現(打表找規律),將全0串放最前面明顯是最優的。所以,我自然而然地想到了貪心。
解法
我們先設f[i],將01串按上述做好。設m[i]為第i次檢查出的01串是f陣列中的第m[i]個,DG判斷是否能放入,可以就往下DG。如果方案成立直接輸出。
注意
當dg查詢到第X層(x>2^n-n+1)時,我們就要特殊處理,因為查詢會迴圈到頭,所以我們要判斷在末尾的那段是否成立,且該01串結尾是否都為0。
var
n,k,i,j,o,l,q:longint;
bz:array[1..4096 ]of boolean;
m:array[1..4096]of longint;
p:char;
ans,g:ansistring;
f:array[1..4096]of string;
procedure dg(x:longint);
var
i,j,w:longint;
bj:boolean;
begin
if (x=k+1) then
begin
write(k,' ',f[1]);
for i:=2 to k-n+1 do
write(f[m[i],n]);
writeln;
halt;
end;
if (x>k-n+1) then w:=k-x+1 else w:=n-1;
for i:=1 to k do
begin
bj:=false;
if (bz[i]=false) then
begin
for j:=1 to w do
begin
if (f[i,j]<>f[m[x-1],j+1]) then
begin
bj:=true;
break;
end;
end;
if (w<>n-1) then
begin
for j:=w+1 to n do
if (f[i,j]<>'0') then bj:=true;
end;
if (bj=false) then
begin
bz[i]:=true;
m[x]:=i;
dg(x+1);
bz[i]:=false;
end;
end;
end;
end;
begin
readln(n);
k:=1;
for i:=1 to n do
k:=k*2;
o:=k div 2;
while (o<>0) do
begin
p:='1';
l:=1;
for i:=1 to k div o do
begin
q:=(ord(p)-47)mod 2;
p:=chr(q+48);
for j:=l to l+o-1 do
f[j]:=f[j]+p;
inc(l,o);
end;
o:=o div 2;
end;
ans:='2';
m[1]:=1;
bz[1]:=true;
dg(2);
end.