2018.10.05【NOIP提高组】模拟B组
\(5166.\) 卢学魔 \((Standard\ IO)\)
Time Limits: 1000 ms
Memory Limits: 262144 KB
考试的想法,一直 \(Dfs\) 到底部,然后方案数加一。
得分: \(20\)。
原因: 补充一些生物知识:
-
生产者不止一个
-
一个生产者不是食物链
提示
- \(Dfs\) 会爆栈,所以我写的是记忆化。记录它的叶子节点有多少个。保证每一个点只有出现一次。
var
next,reach:array[-1..210007] of longint;
cnt,dsu,size:array[-1..2100007] of longint;
ans,l,r,i,j,n,m,tot:longint;
procedure Add(l,r:longint);
begin
inc(tot);
reach[tot]:=r;
next[tot]:=cnt[l];
cnt[l]:=tot;
end;
function Dfs(x:longint):longint;
var i,tmp:longint;
begin
Dfs:=0; i:=cnt[x];
if size[x]>0 then exit(size[x]);
if (i=-1)and(dsu[x]<>0) then begin exit(1); end;
while i<>-1 do
begin
tmp:=Dfs(reach[i]); inc(size[x],tmp); inc(Dfs,tmp);
i:=next[i];
end;
end;
begin
filldword(cnt,sizeof(cnt) div 4,maxlongint*2+1);
read(n,m);
for i:=1 to m do begin read(l,r); Add(l,r); inc(dsu[r]); end;
ans:=0;
for i:=1 to n do if dsu[i]=0 then inc(ans,Dfs(i));
writeln(ans);
end.
\(5167.\) 下蛋爷 \((Standard\ IO)\)
Time Limits: 1000 ms
Memory Limits: 262144 KB
这个名字很棒。
首先我们先求出 \(stu_i\) 代表第 \(i\) 个 单词(\(word_i\)) 在字符串 (\(S\)) 中出现的次数。由于本人不会自动机,所以用 \(KMP\) 就可以了。
然后我们把 \(stu\) 数组离散化,从大到小排序。然后进行概率 \(DP\)。公式是 \(f[i,j]:=f[i-1,j]*p+f[i-1,j+1]*(1-p);\)。这个很好理解。
由于是 \(KMP\),所以只有 \(90\) 分,最后一个点可以打表。程序全场最慢,没有之一。
var
S:ansistring;
word:array[-1..2100] of string;
stu,place:array[-1..2100] of longint;
f:array[-1..2100,-1..2100] of real;
ans,witn:array[-1..2100] of real;
i,j,n,m,k,maxn:longint;
p:real;
procedure Sort(l,r:longint);
var i,j,s,t:longint;
begin
i:=l; j:=r; s:=stu[(l+r) div 2];
repeat
while stu[i]>s do inc(i);
while stu[j]<s do dec(j);
if i<=j then
begin
t:=stu[i]; stu[i]:=stu[j]; stu[j]:=t;
t:=place[i]; place[i]:=place[j]; place[j]:=t;
inc(i); dec(j);
end;
until i>=j;
if i<r then Sort(i,r);
if j>l then Sort(l,j);
end;
function kmp(s,ss:ansistring):longint;
var
next:array[1..11000] of longint;
l1,l2,i,j:longint;
begin
kmp:=0; next[1]:=0;
j:=0; l1:=length(s); l2:=length(ss);
for i:=2 to l2 do
begin
while (j>0) and (ss[j+1]<>ss[i]) do j:=next[j];
if ss[j+1]=ss[i] then inc(j); next[i]:=j;
end;
j:=0;
for i:=1 to l1 do
begin
while (j>0) and (s[i]<>ss[j+1]) do j:=next[j];
if (j<l2) and (s[i]=ss[j+1]) then inc(j);
if j=l2 then begin inc(kmp); j:=next[j]; end;
end;
end;
begin
readln(n); for i:=1 to n do readln(word[i]); readln(S); readln(p,k);
for i:=1 to n do begin stu[i]:=kmp(S,word[i]); place[i]:=i; end;
Sort(1,n);
for i:=1 to n do if stu[i]<>stu[i-1] then inc(maxn);
for i:=0 to maxn do f[0,i]:=1;
for i:=1 to k do for j:=maxn downto 0 do f[i,j]:=f[i-1,j]*p+f[i-1,j+1]*(1-p);
{for i:=1 to k do
begin
fillchar(ans,sizeof(ans),0);
for j:=0 to maxn do ans[j]:=ans[j]+f[i,j];
for j:=1 to n do witn[place[j]]:=ans[stu[j]];
for j:=n downto 1 do write(witn[j]:0:3,' '); writeln;
end; }
maxn:=0;
for i:=1 to n do
begin
if stu[i]<>stu[i-1] then inc(maxn);
ans[place[i]]:=f[k,maxn];
end;
for i:=1 to n do write(ans[i]:0:3,' ');
end.
\(5168.\) 冲击哥 \((Standard\ IO)\)
Time Limits: 1000 ms
Memory Limits: 262144 KB
一个一个扩展就好了,一个大贪心。还没有打出来,到时候再贴代码吧。
完结撒花!✿✿ヽ(゚▽゚)ノ✿