2016.10.5初中部上午NOIP普及组比赛总结

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.

posted @ 2016-10-06 07:28  jz_597  阅读(119)  评论(0)    收藏  举报