题解 P5051 【[COCI2017-2018#7] Timovi】

看到这道题目,数据范围,心凉了一大截

这是没开O2的

而这是开了O2的

emm……本蒟蒻也无言以对呀

好了,回归正题,看到题目的标签,高性能,自然而然地想到了快读

相信做这题的大佬们一定知道吧!

快读,从字面上来理解就是____

答案:快速读入

我们都知道,读入一个字符比读入一个整数要快得多。

那么这就好办了!我们又知道,每一个字符都有它自己的ASCII码,那么,我们是不是只要将输入的字符减去字符0的ASCII码48就可以了呢?

显然是这样。

下面放出快读的代码,有注释,不懂的还可以问问老师和同学。

int read(){//快读,read
    int r=0,f=1;//r为计数器,f为标志,看是整数还是负数
    char c=getchar();//读入c
    while((c<'0'||c>'9')&&c!='-')//读入非数字、负号的字符
        c=getchar();
    if(c=='-')//特判c,若c为负号则f置-1,即为负数
        f=-1,c=getchar();
    while(c<='9'&&c>='0')//正式读入数字
        r=r*10+c-'0',c=getchar();//r由c-0的ASCII码组成
    return r*f;//若f为1则为负数,f为-1则为负数
}

很简单吧?

下面,关键代码!要认真哟就是干货

大家看到题面,千万不要想当然地认为就是1~n整个加两遍

睁大眼睛,咦?每回 2 ~ n - 1加了两遍,而 1 和 n 只加了一遍

这就是问题所在! 本蒟蒻一开始就错了这个地方

所以,核心代码重磅来袭

while(m>0){
    for(i=1;i<=n&&m>0;i++,m-=k)//在for循环中可以有多个条件语句
        a[i]+=min(m,k);//上面中间意思是说i≤n且m>0时做后面的条件
    for(i=n-1;i>=2&&m>0;i--,m-=k)//后面意思是说在i减1的同时m减k
        a[i]+=min(m,k);//为什么用min?因为当m不足k时应减m而不是k
}

这里 for 循环有一点儿难,好好理解

其实,弄清 for 循环的结构也就不难了:

很简单吧?这样解释上面的结构就不成问题了

其实说是橙题,但我觉得实际的难度是绿题

好吧,下面放出代码最终版!

相信听了我解释的同学们都弄懂了吧!

代码来喽!

// luogu-judger-enable-o2
//这是必须得开的,不然,目之所及尽是TLE
#include<cstdio>
#include<queue>
#define maxn 200010//定义maxn为200010
using namespace std;//本蒟蒻代码中不可或缺的成分
int n,k,m,a[maxn],i;
int read(){//快读
    int r=0,f=1;
    char c=getchar();
    while((c<'0'||c>'9')&&c!='-')
        c=getchar();
    if(c=='-')
        f=-1,c=getchar();
    while(c<='9'&&c>='0')
        r=r*10+c-'0',c=getchar();
    return r*f;
}
int main(){
    n=read(),k=read(),m=read();//read()的正确使用,get一下
    while(m>0){//核心代码
        for(i=1;i<=n&&m>0;i++,m-=k)
            a[i]+=min(m,k);
        for(i=n-1;i>=2&&m>0;i--,m-=k)
            a[i]+=min(m,k);
    }
    for(i=1;i<=n;i++)//输出a数组
        printf("%d ",a[i]);//别忘了空格!
    return 0;
}

OI加油!洛谷冲鸭!

转载于:https://www.cnblogs.com/SeashellBaylor/p/11079665.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值