USACO/DEC/BR3

P9976 [USACO23DEC] Farmer John Actually Farms B

题目传送门

分析

首先我们可以先按,符合的位置,小到大排序,小的位置代表希望长的最高的地方

初始高度为 $ h[ i ] $ , 增长速度为 $ a[ i ] $ ,天数为 $ d $

如果 $ h[0]+da[0] > h[1]+da[1] > h[2]+da[2] ...>h[n-1]+da[n-1] $ 符合,d成立

$ h[i]+da[i] > h[i+1]+da[i+1] $

$ d*(a[i]-a[i+1]) > h[i+1]-h[i] $

$ 判断 a[i]-a[i+1]正负决定移项变号 $

$ if > 0$ 则 $d >\dfrac{h[i+1]-h[i]}{a[i]-a[i+1]} $

$ if < 0$ 则 $d <\dfrac{h[i+1]-h[i]}{a[i]-a[i+1]} $

那我们 $ d $ 所在的区间处理好就可以做了,但要处理==0的特殊情况,还有考虑相除为分数的情况等

AC code

#include <bits/stdc++.h>
using namespace std;

struct gu{
	int h,a,l;
};

bool cmp(gu g1,gu g2){
	if(g1.l<g2.l) return true;
	return false;
}

int main(){
	int t,n;
	gu g[200005];
	cin >> t;
	while(t--){
		cin >> n;
		for(int i=0;i<n;i++){
			cin >> g[i].h;
		}
		for(int i=0;i<n;i++){
			cin >> g[i].a;
		}
		for(int i=0;i<n;i++){
			cin >> g[i].l;
		}
		sort(g,g+n,cmp);
		if(n==0){
			cout << 0;
			break;
		}
		// h[0]+d*a[0] > h[1]+d*a[1] > h[2]+d*a[2] ...
		double u = 1e9,d = -1e9;// d为下边界 u为上边界 
		bool jud = true;
		//转化跟思路是一样的,只是移项略不同 
		for(int i=0;i<n-1;i++){
			if(g[i+1].a-g[i].a<0){
				d = max(d,1.0*(g[i].h-g[i+1].h)/(g[i+1].a-g[i].a));
			}
			else if(g[i+1].a-g[i].a>0){
				if((g[i].h-g[i+1].h)%(g[i+1].a-g[i].a)==0){
					u = min(u,1.0*(g[i].h-g[i+1].h)/(g[i+1].a-g[i].a)-1);
				}
				else{
					u = min(u,1.0*(g[i].h-g[i+1].h)/(g[i+1].a-g[i].a));
				}
			}
			else{
				if(g[i].h>g[i+1].h) continue;//i 位置永远高 i+1 
				else{
					jud = false;
					break;
				}
			}
		}
		d = floor(d)+1;
		u = floor(u);
		int p;
		if(jud==false) p=-1;
		else if(d>u) p=-1;
		else if(d<=0&&u>=0) p=0;
		else p=d;
		cout << p << endl;
	}
	return 0;
}
posted @ 2023-12-21 20:47  Nijika  阅读(18)  评论(0)    收藏  举报