51nod-1243 Problems with row boats

Topic source:  Codility
Baseline Time Limit: 1 second Space Limit: 131072 KB Score: 40  Difficulty: Level 4 Algorithm Questions
 collect
 focus on
There are N ships and N stakes in a pier, the length of the ship is 2*X, the width of the pier is M, and the positions of the N stakes (relative to the left bank of the pier) will be given in the data. There can be no overlap between boats, i.e. the bow of each boat cannot go beyond the stern of the previous boat, and certainly not beyond the sides of the pier. The boat and the stake are connected by a rope, and one stake can only be tied to one boat. One end of the rope is tied to the stake, and the other end is tied to the middle of the boat. And the distance from the middle of the boat to the stake is the length of rope required. It is up to you to arrange the position of the boat so that the longest rope used is the shortest. Output the shortest length, or -1 if the dock does not fit all the boats.


For example: N = 3, X = 2, M = 16. The positions of the three stakes are: 1 3 14. The length of the boat is 2*X = 4. You can place the three boats at 2 6 14 (referring to where the boats are in the middle), so that there is no overlap between the boats and the longest rope used is the shortest length of 3, which is the second boat The distance from the boat to the second stake.
Input
Line 1: 3 numbers N X M separated by spaces (1 <= N <= 50000, 1 <= X <= 10^9, 1 <= M <= 10^9).
Lines 2 - N + 1: 1 number Pi per line, corresponding to the position of the stake (0 <= Pi <= Pi+1 <= M), and the data given is ordered.
Output
Output the minimum value of the longest rope. Output -1 if the dock does not hold all ships.
Input example
3 2 16
1
3
14
Output example
3

Answer to the question: It is obvious that the answer can be divided into two parts, and it is not clear how to dp. . . . . It is said that it can be O(n), but I don't know how to operate it.

AC code

#include <stdio.h>
#include <iostream>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#include <string.h>
#include <cmath>
typedef long long ll;
 
using namespace std;

const ll maxn = 55555;
ll loc[maxn];

bool can(ll m, ll n, ll x, ll y){
	ll r = 0;				//记录当前最右边船的船尾位置 
	for(ll i = 0; i < n; i++){
		if(r + x + m >= loc[i])
			r = r + 2 * x;
		else if(loc[i] - m - x >= r)
			r = loc[i] - m + x;
		if(r - x - loc[i] > m)
			return false;
	}
	if(r <= y)
		return true;
	else
		return false;
}

int main(){
	ll n, x, m;
	scanf("%lld%lld%lld", &n, &x, &m);
	for(ll i = 0; i < n; i++)
		scanf("%lld", &loc[i]);
	if(m < n * 2 * x){
		printf("-1\n");
		return 0;
	}
	ll l = 0, r = m;
	while(l < r){
		ll m1 = (l + r) / 2;
		if(can(m1, n, x, m))
			r = m1;
		else
			l = m1 + 1;
	}
	printf("%lld\n", l);
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325991405&siteId=291194637
Row