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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值