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;
}

浙公网安备 33010602011771号