小测试题解

 

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

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

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

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

 

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

转载于:https://www.cnblogs.com/Randolph87/p/3618098.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值