题解:P11299 [NOISG2021 Finals] Fraud
reinforest · · 题解
建议评黄。
本题实际上是让你找到满足条件的正整数
如果
如果
那么,我们实际上可以令
为什么可以这么做?因为
所以
好,现在我们令
我们拿出其中任意一个不等式组,可以整理得:
对其分类讨论:
- 当
B_i - B_{i+1} > 0 时:Y > \frac{A_{i+1} - A_{i}}{B_i - B_{i+1}} - 当
B_i - B_{i+1} < 0 时:Y < \frac{A_{i+1} - A_{i}}{B_i - B_{i+1}} - 当
B_i - B_{i+1} = 0 时:如果A_{i+1} - A_{i} \ge 0 ,那么输出NO即可。
因此,我们可以想到用两个数
如果你想使用 double,注意这道题对精度有很高的要求,建议把 eps 设成 1e-12。
使用 double 的代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,a[300005],b[300005];
double mx=1e18,mn=-1e18;//上界与下界
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&b[i]);
}
for(int i=1;i<n;i++){
if(b[i+1]>b[i]){
mx=min(mx,(1.0*a[i+1]-1.0*a[i])/(1.0*b[i]-1.0*b[i+1]));
}else if(b[i+1]<b[i]){
mn=max(mn,(1.0*a[i+1]-1.0*a[i])/(1.0*b[i]-1.0*b[i+1]));
}else if(a[i+1]>=a[i]){
printf("NO\n");
return 0;
}
}
if(mx-mn<0 || fabs(mx-mn)<1e-12 || mx<1e-12){
printf("NO\n");
}else{
printf("YES\n");
}
return 0;
}
用分数进行处理(避免精度问题)的代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,a[300005],b[300005];//上界与下界
struct frac{
ll zi,mu;
}mx,mn;
frac make_frac(ll a,ll b){
if(b<0)return (frac){-a,-b};
else return (frac){a,b};
}
frac maxx(frac a,frac b){
if(a.zi*b.mu-b.zi*a.mu<0)return b;
else return a;
}
frac minn(frac a,frac b){
if(a.zi*b.mu-b.zi*a.mu<0)return a;
else return b;
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&b[i]);
}
mx={1000000000,1};
mn={-1000000000,1};
for(int i=1;i<n;i++){
if(b[i+1]>b[i]){
mx=minn(mx,make_frac(a[i+1]-a[i],b[i]-b[i+1]));
}else if(b[i+1]<b[i]){
mn=maxx(mn,make_frac(a[i+1]-a[i],b[i]-b[i+1]));
}else if(a[i+1]>=a[i]){
printf("NO\n");
return 0;
}
}
if(mx.zi*mn.mu-mn.zi*mx.mu<=0 || mx.zi<=0){
printf("NO\n");
}else{
printf("YES\n");
}
return 0;
}