题目:http://codeforces.com/problemset/problem/1015/D
题目大意:1~n个房子,起点为1,然后规定刚好k步,走完s的距离,(从x到y,距离为|x-y|).
思路:以为是个深搜。但是感觉写不了。。。看了官方题解。(蠢了)。左右走无法判断。
官方给了 cur + x 和 cur - x 来左右走。怎么保证刚好k步s距离呢。 s-(k-1)
如果s-(k-1) > (n-1) 走最大的距离,然后k -= 1, s -= l; (l为他俩的最小值)
当k等于1,剩最后s',就保证刚好走完s。k != 1, 总还会剩一点。比较巧妙
不能刚好k步走完s,当且仅当 k > s or k*(n-1) < s
能继续走,当且仅当 k-1 <= s-x x <= n-1 也就是min(n-1, s-(k-1));
AC代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
ll step(ll cur, ll x) {
if(cur - x > 0)//能左走就先左走
return cur - x;
else//不行就右走
return cur + x;
}
int main() {
//freopen("in.txt", "r", stdin);
ll n, k, s, cur = 1;
scanf("%lld%lld%lld", &n, &k, &s);
if(k > s || k*(n-1) < s) {//只有这两种情况NO
printf("NO\n");
return 0;
}
printf("YES\n");
while(k > 0) {//先走最大的,直到最后不足最大的,然后一点点走。
ll l = n-1 < s-(k-1) ? n-1 : s-(k-1);// s-(k-1)能保证k步刚好s距离
cur = step(cur, l);//左走还是右走
printf("%lld ", cur);
s -= l;
k -= 1;
}
}