Description
一场比赛有n支队伍参加,每队两人,按最终排名从高到低输出每支队伍两个人的得分a[i],b[i],问是否存在一[0,1]间的x,使得x*max(a[i],b[i])+(1-x)*min(a[i],b[i])也是随着i的增加非减的
Input
第一行一整数n表示队伍数,之后n行每行输入该队两个队员的得分a[i]和b[i] (1<=n<=1e6,1<=a[i],b[i]<=1e4)
Output
如果存在合法的x则输出YES,否则输出NO
Sample Input
3
2106 1946
1955 1859
1778 1669
Sample Output
YES
Solution
不妨设a[i]>=b[i],那么如果存在合法的x,那么对1<=i<=n-1有x*a[i]+(1-x)*b[i]<=x*a[i+1]+(1-x)*b[i+1],即(a[i]-b[i]-a[i+1]+b[i+1])*x<=b[i]+b[i+1]
之后根据a[i]-b[i]-a[i+1]+b[i+1]和b[i]+b[i+1]的符号来限定x的上下限,最后如果下限大于上限则无解,否则有解,注意控制精度
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 1111111
#define eps 1e-11
int n,a[maxn],b[maxn];
double l,r;
bool check()
{
for(int i=1;i<n;i++)
{
int x=a[i]-b[i]-a[i+1]+b[i+1],y=b[i+1]-b[i];
if(x==0)
{
if(y<=0)continue;
return 0;
}
else if(x>0)
{
if(y<=0)continue;
l=max(l,1.0*y/x);
}
else
{
if(y>0)return 0;
r=min(r,1.0*y/x);
}
}
if(l-eps>r)return 0;
return 1;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
if(a[i]<b[i])swap(a[i],b[i]);
}
l=0,r=1;
printf("%s\n",check()?"YES":"NO");
}
return 0;
}