码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #501 (Div. 3) D Walking Between Houses

时间:2018-08-16 10:38:26      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:clu   才有   while   代码   using   round   比较   之一   cin   

翻译

给你一条数轴(出题人很喜欢数轴啊),上面有排列着\(n\)个点,编号为\(1\)\(n\)(你开始在\(1\))。每次你要从一个点移动到另一个点(可以重复)。移动距离为两点坐标之差的绝对值,问你是否能否在\(k\)次机会内里一共移动\(s\)距离,并输出方案。

思路

第四题还是比较难的,赛后想了几分钟时才有头绪。

毫无疑问还是贪心(出题人很喜欢贪心啊)!那么我们分类讨论,先看不合法的情况

  • 无论如何走你也走不到那个距离

  • 无论如何走你也会走超那个距离

看来只要能走到那个距离除外都是不合法的,因此就一个走超和走不到(我没废话!)。

那么如何解决?很简单,走不到就是每次你从最左边走到最右边,再从最右边走到最左边,这样循环下去,一直到你走完了还不到。

走超了就是你每次走一个距离,进行\(k\)次后还是大于\(s\)

那么这两个代码好写极了,不用我教你吧\(^_^\)

到了合法的情况,受到不合法的启发,我们可以想到这样的方法:每一次啊,先从最左边走到最右边,再从最右边走到最左边,循环下去,一直到你剩下的距离不足\(n-1\)(\(n-1\)就是数轴两个端点间的距离)的时候啊,直接走完即可(由于在此期间你只会位于数轴的两个端点)。

但是不会那么简单的\(QAQ\),直接走完可不行啊,如果要走\(32\)那么远,\(4\)下子走完,数轴有\(11\)个点。照我们说的,当还有两个长度的时候,我们一步走完,呀!怎么还有一下!!

所以说,我们可以这样想:当剩下的距离不足\(n-1\)的时候,我们尝试分成多部走,很多种方法,我的有点麻烦,某位大佬写的是:走\(s-k\)\(s\)是剩下的距离)的步数。感觉自己恍然大悟了(不懂你可以算算,由于是\(s-k\),这样就巧妙的拆分成了多部分)!

一定要用long long\(CF\)的题就这个尿性)!

恐怕上述的方法是最简单的方法之一了吧,上代码(有两个细节在代码里注释了):

Code

#include<iostream>
using namespace std;
int main()
{
    long long n,k,s,a=1;
    cin>>n>>k>>s;
    if(s>(n-1)*k||k>s)
        return cout<<"NO"<<endl,0;
    cout<<"YES"<<endl;
    while(k--)
    {
        int r=min(s-k,n-1);//选区n-1与s-k中最小的,因为当s-k比n-1大的时候,我们要先消去 
        s-=r;
        if(a+r<=n)//看看往哪个方向走。 
            a+=r;
        else a-=r;
            cout<<a<<" ";
    }
    return 0;  
}

Codeforces Round #501 (Div. 3) D Walking Between Houses

标签:clu   才有   while   代码   using   round   比较   之一   cin   

原文地址:https://www.cnblogs.com/lyfoi/p/9485066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!