1. 程式人生 > >Codeforces Round #501 (Div. 3) 1015D Walking Between Houses

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

題目大意: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;
	}
}