17.9.16B组总结
真的吐槽一下,为什么C组之前有矩阵乘法的题而B组没有,害得我又要新学(感觉自己不如C组)。。。
T1
赤裸裸的一道大水题,每次将输入的好朋友的值加上其值,将答案减去其值(即为w),最后将大于0的值加入答案,其他的不要理他就好了(其实就是一个贪心罢了)。
T2
一开始满心欢喜地认为是找规律,找哇找,发现······(一脸懵逼)。
DP,设f[i,j]表示i维j步的方案数,方程就是:
f[i,j]=∑k=1jf[i−1,k]+C2∗(j−k)2∗(n−k)+Cj−k2∗(j−k)
C可以用杨辉三角预处理出来。
T3
完美的表示没学过矩阵乘法。
先贴个矩阵乘法的链接:
https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95/5446029?fr=aladdin
再贴个仿射变换的链接:
https://baike.baidu.com/item/%E4%BB%BF%E5%B0%84%E5%8F%98%E6%8D%A2/4289056?fr=aladdin
这两个东西是这题必不可少的,很多人问为什么矩阵是3*3的,我表示我也不会证,自己看第二个链接。
看懂了就很容易了,只要打个递归(暴力枚举,但跳过循环,直接求值),再码个矩阵的快速幂,就好了。(记得预处理,很复杂,我码了2000+)。
贴代码:
矩阵快速幂:
procedure mi(var aa:arr;x:longint);
var
cc:arr;
i:longint;
begin
fillchar(cc,sizeof(cc),0);
for i:=1 to 3 do
cc[i,i]:=1;
while x>0 do
begin
if x and 1=1 then
did(cc,aa);
did(aa,aa);
x:=x>>1;
end;
aa:=cc;
end;
递归:
procedure dg(st,en:longint);
var
ff,g:arr;
i:longint;
s1,s2:extended;
begin
fillchar(ff,sizeof(ff),0);
fillchar(g,sizeof(g),0);
for i:=1 to 3 do
ff[i,i]:=1;
i:=st;
while i<=en do
begin
fillchar(g,sizeof(g),0);
case zz[i] of
1:
begin
g[1,1]:=1;
g[2,2]:=1;
g[3,1]:=z[i,2];
g[3,2]:=z[i,3];
g[3,3]:=1;
did(ff,g);
end;
2:
begin
g[1,1]:=z[i,2];
g[2,2]:=z[i,3];
g[3,3]:=1;
did(ff,g);
end;
3:
begin
z[i,2]:=360-z[i,2];
s1:=cos(rad(z[i,2]));
s2:=sin(rad(z[i,2]));
g[1,1]:=s1;
g[1,2]:=s2;
g[2,1]:=-s2;
g[2,2]:=s1;
g[3,1]:=s2*z[i,4]-s1*z[i,3]+z[i,3];
g[3,3]:=1;
g[3,2]:=-s1*z[i,4]-s2*z[i,3]+z[i,4];
did(ff,g);
end;
4:
begin
dg(i+1,ee[i]-1);
mi(h,sss[i]);
did(ff,h);
i:=ee[i];
end;
end;
inc(i);
end;
h:=ff;
end;
求答案:
for i:=1 to n do
begin
fillchar(f,sizeof(f),0);
f[1,1]:=x[i];
f[1,2]:=y[i];
f[1,3]:=1;
did(f,h);
writeln(f[1,1]:0:8,' ',f[1,2]:0:8);
end;