2016.10.5初中部上午NOIP普及组比赛总结
这次的题目出得挺有质量的。但我觉得我更应该努力了。
进度:
比赛:0+20+0+0=20
改题:AC+AC+AC+AC=AK
kk的作业
这题我错得……文件输入输出……别提了,听题!
题目简化:
上一行的数之积/下一行的数之积
不能用小数,用分数(记得化简)。
接输出’0’+#13+’1’
暴力地把分子和分母分别乘起来。
然后除以它们的最大公因数(gcd)
也就是约分。
后来感觉会爆。
所以我后来又改了一种方法:
每次两边都分别给fz(分子)和fm(分母)乘一个,
然后就约分。
但我感觉需要高精度除法,所以没做高精度。
错因:
文件输入输出。
变量超出范围。
正解:
我很快改好这题了。
其实可以把那些数存在数组里,然后两两约分。
最后才用高精度乘法把它们一个一个地乘出来。
zy的秘密
丢了40分。
题目简化:
单源最短路径问题。
可答案要求dis数组里除maxlongint之外最大的。
比赛思路:
我一开始不知道这是最短路径,
用了递归60分。
后来担心爆栈,
我就把它改成宽搜了。
却因为一些细节,我的宽搜20分。
40分没了。
错因:
递归时超。
正解:
可以用SPFA算法做。
也可以像我这样宽搜。
zy送画
打了好久的爆搜……事实证明打爆搜很复杂……
题目简化:
两个人从左上角走到右下角。
中间不许重复。
问中间经过的数最大和。
比赛思路:
一个矩阵变成两个矩阵,一个在左上,一个在右下。
求出对应点,bz时就两个一起标。
然后爆搜……
错因:
时间不够,没编完。
正解:
设f[i1,j1,i2,j2]为第一人到(i1,j1),第二人到(i2,j2)时的最大和。
方程不用说了,有几个方向能够过来。
wd的假日
一开始以为是什么背包。最后慌慌忙忙打了爆搜,结果……
文件输入输出,还漏了些细节。
题目简化:
有一个人,有很多的工作,
至少做m个工作。每做一个工作,就会得到一些钱。
但打游戏也可以赚钱,有一些时间必须要打游戏。
比赛思路:
想了很久背包,
最后慌忙地打上爆搜。
错因:
漏了一些细节。
正解:
递归就行了,
不需要加记忆化。
题外话:
1. 这次的题虽然有难度,但也好消化。
2. 好开心!我猛地发现我通过第二题推出了SPFA!还是我自己推出的!别人讲时太复杂了,我听不懂。但因为这道题是单源的,我甚至不知道是最短路径问题,居然通过爆搜推出SPFA!当我检查时才发现!(也许是因为这题比较有针对性吧)。
SPFA:
Program SPFA;
const
max_data=100000;
var
n,m,i,j,x,y,ans,head,tail:longint;
a:array[1..1000,1..1000]of longint;
d:array[1..max_data]of longint;
dis:array[1..1000]of longint;
bz:array[1..1000]of boolean;
procedure read_;//读入
procedure init;//初始化
begin
for i:=1 to n do
for j:=1 to n do
a[i,j]:=maxlongint;
for i:=1 to n do a[i,i]:=maxlongint;
for i:=1 to n do dis[i]:=maxlongint;
for i:=1 to max_data do d[i]:=0;
end;
begin
readln(n);
readln(m);
init;
for i:=1 to m do
begin
read(x,y);
readln(a[x,y]);
a[y,x]:=a[x,y];//如果是有向图就别加
end;
end;
procedure write_;//输出
begin
for i:=2 to n do
if dis[i]<maxlongint then write(dis[i],' ')else write('-1 ');
end;
procedure spfa;
begin
head:=0;
tail:=1;
d[1]:=1;
dis[1]:=0;
repeat
inc(head);
if head>max_data then head:=1;
for i:=1 to n do
begin
if not(a[d[head],i]<maxlongint)then continue;
inc(tail);
if tail>max_data then tail:=1;
d[tail]:=d[head];
d[tail]:=i;
if dis[d[head]]+a[d[head],d[tail]]>=dis[d[tail]] then
begin
dec(tail);
if tail=0 then tail:=max_data;
continue;
end else dis[d[tail]]:=dis[d[head]]+a[d[head],d[tail]];
if bz[d[tail]] then
begin
dec(tail);
if tail=0 then tail:=max_data;
continue;
end;
bz[d[tail]]:=true;
end;
bz[d[head]]:=false;
until head=tail;
end;
begin
read_;
spfa;
write_;
end.