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

题目: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;
	}
}


猜你喜欢

转载自blog.csdn.net/qq_40932661/article/details/81411954