小测试题解

小测试题解

 

一开始就想到一个暴力的做法(虽然也知道正解应该是后缀自动机)

把每一个字符串的每一个前缀都倒着加入字典树

然后就变成了经典的树博弈(根节点不能取,因为根是空的)

sg函数为,子树sg的xor和加权值(除根节点外权值都为1,因为每一个节点都只代表一个字符串)

但是这样是n方的,不过不会后缀自动机所以只好暴力

用后缀自动机的话就是建parent树,然后做带权值的树博弈(其实和普通的树博弈差不多,普通的只是权值都为1而已,权值为这个节点代表的字符串个数)

 

  1 {$M 50000000}

  2 const

  3     maxn=2000010;

  4 type

  5     node=record

  6       go:array['0'..'9']of longint;

  7       step,fa:longint;

  8     end;

  9 

 10 var

 11     sam:array[0..maxn]of node;

 12     first,stop,next,min:array[0..maxn]of longint;

 13     s,ans:ansistring;

 14     tot,last,t,num:longint;

 15 

 16 procedure add(x:char);

 17 var

 18     now,new,q:longint;

 19 begin

 20     inc(tot);

 21     now:=tot;

 22     fillchar(sam[now].go,sizeof(sam[now].go),0);

 23     sam[now].step:=sam[last].step+1;

 24     while (last<>0)and(sam[last].go[x]=0) do

 25       begin

 26         sam[last].go[x]:=now;

 27         last:=sam[last].fa;

 28       end;

 29     if last=0 then sam[now].fa:=1

 30     else

 31       begin

 32         q:=sam[last].go[x];

 33         if sam[q].step=sam[last].step+1 then sam[now].fa:=q

 34         else

 35           begin

 36             inc(tot);

 37             new:=tot;

 38             sam[new]:=sam[q];

 39             sam[q].fa:=new;

 40             sam[now].fa:=new;

 41             sam[new].step:=sam[last].step+1;

 42             while (last<>0)and(sam[last].go[x]=q) do

 43               begin

 44                 sam[last].go[x]:=new;

 45                 last:=sam[last].fa;

 46               end;

 47           end;

 48       end;

 49     last:=now;

 50 end;

 51 

 52 procedure insert(x,y:longint);

 53 begin

 54     inc(num);

 55     stop[num]:=y;

 56     next[num]:=first[x];

 57     first[x]:=num;

 58     min[y]:=sam[x].step+1;

 59 end;

 60 

 61 function dfs(x:longint):longint;

 62 var

 63     i:longint;

 64 begin

 65     dfs:=0;

 66     i:=first[x];

 67     while i<>0 do

 68       begin

 69         dfs:=dfs xor dfs(stop[i]);

 70         i:=next[i];

 71       end;

 72     inc(dfs,sam[x].step-min[x]+1);

 73 end;

 74 

 75 procedure main;

 76 var

 77     i:longint;

 78 begin

 79     readln(s);

 80     for i:=1 to tot do

 81       first[i]:=0;

 82     last:=1;

 83     tot:=1;

 84     fillchar(sam[1].go,sizeof(sam[1].go),0);

 85     for i:=1 to length(s) do

 86       add(s[i]);

 87     for i:=2 to tot do

 88       insert(sam[i].fa,i);

 89     if dfs(1)=1 then writeln('codechef')

 90     else writeln('topcoder');

 91 end;

 92 

 93 begin

 94 assign(input,'game.in');

 95 reset(input);

 96 assign(output,'game.out');

 97 rewrite(output);

 98     readln(t);

 99     while t<>0 do

100       begin

101         main;

102         dec(t);

103       end;

104 close(input);

105 close(output);

106 end.
View Code

 

 

2.期望面积

(qs.pas/c/cpp/in/out)

Description

给定平面上n个点及其出现的概率,问这n个点中出现的那些点组成的凸包面积期望是多少,如果凸包退化为直线则视其面积为0 保证不出现三点共线

 

Input

首先输入一个整数n (0 < n ≤ 100).,给定点的个数,之后n行每行输入两个整数x,y(-1000 ≤ x, y ≤ 1000),和一个小数p(0 ≤ p ≤ 1)表示n个点的坐标及其出现的概率,输入数据保证p最多有4位小数

对于1%的数据n<=2

 对另外于29%的数据n<=3

对于100%的数据 0<n<=100, -1000 ≤ x, y ≤ 1000,0 ≤ p ≤ 1

Output

输出期望面积,答案保留6位小数,具体格式见sample output

 

Sample Input

3

0 0 0.1

1 0 0.1

1 1 0.1

 

Sample Output

0.000500

 

暴力想法,枚举每一种情况,然后计算凸包面积,再计算期望(考场上只想到拿前面的n<=3的情况)

虽然不可行,但是暴力总是提供基本思想

打完暴力就有想法了,求完凸包再求面积,我们是怎么求面积的呢,一般都是用叉积求的吧

然后我们发现当i->j这个有向线段算进面积的时候当且仅当i和j都出现且在i->j右边的点都没有出现

所以i->j这条有向线段的贡献就是叉积(点i,点j)*pi*pj*П(1-pk(k在i->j右方)),因为没有三点共线所以不要想太多,没有特殊情况

O(n^3)

 

 1 const

 2     maxn=105;

 3 var

 4     x,y,p:array[0..maxn]of double;

 5     n:longint;

 6     ans:double;

 7 

 8 procedure init;

 9 var

10     i:longint;

11 begin

12     read(n);

13     for i:=1 to n do

14       read(x[i],y[i],p[i]);

15 end;

16 

17 function cj(x1,y1,x2,y2:double):double;

18 begin

19     exit(x1*y2-y1*x2);

20 end;

21 

22 procedure work;

23 var

24     i,j,k:longint;

25     s:double;

26 begin

27     for i:=1 to n do

28       for j:=1 to n do

29         if i<>j then

30         begin

31           s:=cj(x[i],y[i],x[j],y[j])*p[i]*p[j];

32           for k:=1 to n do

33             if (k<>i)and(k<>j) then

34             if cj(x[k]-x[i],y[k]-y[i],x[j]-x[i],y[j]-y[i])<=0 then s:=s*(1-p[k]);

35           ans:=ans+s;

36         end;

37     write(abs(ans/2):0:6);

38 end;

39 

40 begin

41     init;

42     work;

43 end.
View Code

 

第三题待码.........

你可能感兴趣的:(测试题)