这次补个D题吧,E1,E2 回头再看
D题解题思路:
- 这个题首先要注意两点
- 第一,如果是(n - 1) * k < s,那么不能够完成,因为(n - 1)* k 是走的最大的步数
- 第二, 如果 s < k,那么也不符合,因为每次走一步的话也肯定会超过s,所以不符合
- 然后其余的情况都是YES
- 根据贪心的思想,我们肯定是一开始走比较大的距离,后面剩的距离我们慢慢走完
- 这里是看大佬的代码,很神奇
while(k--){
int t = min(n - 1, s - k);
s -= t;
if (t + st <= n) st = t + st;
else st = st - t;
printf("%d ",st);
}
- 这里 t = min(n - 1, s - k) 这里的原理就是如果能走更多,那么我们肯定是走n - 1,如果有步数限制,不能走那么多,我们就走s - k,后者相当于是: n = 10, s = 4, k = 3, 我们走3次,那么我们首先走s - k (这里的k - 1了),所以我们首先走2步,然后走1步,再走一步,而不能一下走9(n - 1)步了
- 然后对于下面的t + st <= n 这个很好理解,就是如果没到n,那么我们就往前走
- 对于st = st - t, 因为往前走超过n了,所以我们需要往后走,这里可以成立的原因是因为,我们当前走的距离肯定是小于等于上上一次走的距离的(int t = min(n - 1, s - k)) t 肯定是不变或者变小的,肯定没有上升趋势
- 所以就OK了,代码段,但是思维很好,大佬就是强
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main(){
long long n, k;
long long s;
scanf("%lld%lld%lld",&n,&k,&s);
long long res = (n - 1) * k;
if (res < s || s < k){
puts("NO");
return 0;
}
puts("YES");
int st = 1;
while(k--){
int t = min(n - 1, s - k);
s -= t;
if (t + st <= n) st = t + st;
else st = st - t;
printf("%d ",st);
}
puts("");
return 0;
}