Codeforces Round #501 (Div. 3) D. Walking Between Houses (思维,构造)

  • 题意:一共有\(n\)个房子,你需要访问\(k\)次,每次访问的距离是\(|x-y|\),每次都不能停留,问是否能使访问的总距离为\(s\),若能,输出\(YES\)和每次访问的房屋,反正输出\(NO\).

  • 题解:最优解一定是让每次访问的距离为\(s/k\),然后将余数\(s\ mod\ k\)平均分配到前s%k的房屋中,之后每次访问\(s/k\)即可,也就是构造一个类似于\(x\ 1\ x\ 1\ x\ 1\)这样的一个序列,但因为有余数,所以要修改.

  • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
     
    ll n,k,s;
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        cin>>n>>k>>s;
        if(k*(n-1)<s || k>s) puts("NO");
        else{
            puts("YES");
            ll num=s/k;
            ll rest=s%k;
            ll tmp=1;
            for(ll i=1;i<=rest;++i){
                if(tmp==1){
                    tmp=num+2;
                    printf("%lld ",tmp);
                }
                else{
                    tmp=1;
                    printf("1 ");
                }
            }
            for(ll i=rest+1;i<=k;++i){
                if(tmp<=num) tmp+=num;
                else tmp-=num;
                printf("%lld ",tmp);
            }
     
        }
     
        return 0;
    }
    
原文地址:https://www.cnblogs.com/lr599909928/p/13092067.html