前言
今天的状态还不错,一眼全是淼题,想着能拿个大几百,结果╥﹏╥…
T1(Gift)
赛时:
刚看到题目时瞬间炸了,没有题目描述???(一脸懵逼*1)再往下看,好吧,题目全在输入输出里边(吓死宝宝了 )
截图给你们看
呵呵。。。
老师教我们要看数据范围,一瞟,妈呀!
100% t<=100000 a,b,c,d,e,f,g,h<=60 i<=9223372036854775808(搞SM???)
正解
虽然数据范围很大,其实我们可以发现极限数据刚好比in64(long long)大一,于是我们就可以愉快地特(da)判(biao)了。
当然,如果觉得会空超,高精度+快速幂 也是可以的(不过我jio得会时超)
code
var
a,pow:array[0..60]of int64;
i,t,j:longint;
k,ans:qword;
p:boolean;
begin
readln(t);
pow[0]:=1;
for i:=1 to 60 do pow[i]:=pow[i-1]*2;
for i:=1 to t do begin
ans:=0;
p:=true;
for j:=1 to 8 do begin
read(a[j]);
if a[j]<>60 then p:=false;
end;
read(k);
if (p=true)and(k=9223372036854775808) then begin
writeln('18446744073709551616');
continue;
end;
for j:=1 to 8 do
ans:=ans+pow[a[j]];
writeln(ans+k);
end;
end.
(还是很简单的,也不知是哪里脑抽了一下)
T2(Number)
赛时:
乍一眼没看懂,然后推了半小时式子,结果发现理解错题意了。愉(jue)快(wang)地又重新看题,实在不得,怒弃!
正解:
显然可得 4x + 3 = 2(2x + 1) + 1 和 8x + 7 = 2(2(2x + 1) + 1) + 1 所以我们
一直乘2加1就行了。最后答案是
code
const
mo=1000000007;
var
x:qword;
i,j,ans:longint;
begin
read(x);
while(x mod mo)<>0 do begin
x:=x*2+1;
ans:=ans+1;
x:=x mod mo;
end;
if trunc(ans*2/6)<>ans*2/6 then writeln(trunc(ans*2/6)+1)
else writeln(ans*2/6:0:0);
end.
T3(Circle)
赛时:
哇塞!!!这么简单?一眼看出求三角形周长,秒切。
正解:
很明显,当三个圆相切时,它们的直径和是最大的。因此,我们的答案只需要比三个圆心连成的三角形的周长小一些就可以了。
求证:以不共线的三点为圆心的圆一定可以相切。
证明(如图1):
(1)sc的几何型证明方法:连接三个点,以它们中的两个(设它们为点A和点B,另一点为点C)为圆心作两个相切的圆, ⊙A分别与AB、AC交于点D、点E, ⊙B分别交AB、BC于点D、F(⊙A 和 ⊙B 相切于点D),则CF=CE,命题得证;
(2)我的代数证明方法:设 AD = AE = x,BD = BF = y,CE = CF = z,则
,解得
,又因为点A、B、C不共线,所以一定存在 ∆ABC,所以
,因此x、y、z均为正数,因此三个圆一定相切。
同时,根据方程组 ,可以得到 2(x + y +z) = AC + AB + BC,由此得到三个两两相切的圆的直径和就是它们的圆心组成的三角形,所以答案比三角形的周长小一些。
当三角形的周长为整数时,要输出的答案是三角形的周长减一,因为要向下取整。
CODE
var
a,b,c,aa,bb,cc,t,i,j:longint;
len1,len2,len3:real;
begin
readln(t);
for i:=1 to t do begin
readln(a,b,c,aa,bb,cc);
len1:=sqrt(sqr(a-c)+sqr(b-aa));
len2:=sqrt(sqr(c-bb)+sqr(aa-cc));
len3:=sqrt(sqr(a-bb)+sqr(b-cc));
writeln(trunc(len1+len2+len3));
end;
end.
T4(Travel)
赛时:
由于前三题卡了我很多时间,这题没怎么看,直接打了个 -1 就交了。
正解:
对于这题,因为数据范围很小,所以可以先用 Floyd 求是否连通,再把不连通的边 * 2 。在对于整个图跑一遍 SPFA,边跑变更新答案(有点像DP),就可以了。
CODE
var
x,y,s,n,m,k,i,j,o,ans:longint;
a,b:array[0..1000,0..1000] of longint;
f:array[1..1000,0..100] of longint;
d:array[1..1000,1..2] of longint;
bz:array[1..1000,0..100] of boolean;
procedure spfa;
var
l,r,i,j,k,o:longint;
begin
fillchar(d,sizeof(d),0);
fillchar(bz,sizeof(bz),false);
fillchar(f,sizeof(f),$7f div 3);
f[1,0]:=0;
bz[1,0]:=true;
d[1,1]:=1;
d[1,2]:=0;
l:=1;r:=1;
while l<=r do
begin
k:=d[l,1];
j:=d[l,2];
for i:=1 to n do if a[k,i]<>a[0,0] then
begin
if b[i,k]=1 then o:=0 else o:=1;
if f[i,j+o]>a[k,i]+f[k,j] then
begin
f[i,j+o]:=a[k,i]+f[k,j];
if not bz[i,j+o] then
begin
inc(r);
d[r,1]:=i;
d[r,2]:=j+o;
bz[i,j+o]:=true;
end;
end;
end;
bz[k,j]:=false;
inc(l);
end;
end;
begin
readln(n,m,k);
fillchar(a,sizeof(a),$7f div 3);
for i:=1 to n do
for j:=1 to n do b[i,j]:=2;
for i:=1 to m do
begin
readln(x,y,s);
b[x,y]:=1;
if a[x,y]>s then a[x,y]:=s;
end;
for i:=1 to n do
for j:=1 to n do
for o:=1 to n do
if (j<>o) and (i<>o) and (i<>j) then
if (b[i,o]=1) and (b[o,j]=1) then b[i,j]:=1;
for i:=1 to n do
for j:=1 to n do
if a[i,j]<>a[0,0] then a[i,j]:=a[i,j]*b[j,i];
spfa;
ans:=a[0,0];
for i:=0 to k do if ans>f[n,i] then ans:=f[n,i];
if ans=a[0,0] then writeln(-1) else writeln(ans);
end.
反思
1 做题要注意时间
2 要休息好
3 注意时间分配
4 知识点不熟