链接:https://www.nowcoder.com/acm/contest/140/C
来源:牛客网
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
There is an infinite plane. White Cloud has n lines which are not parallel to the Oy axis. These lines in the plane are in the form y=ax+b.
White Rabbit will have a trip in the plane. It will start at time 0 and go straight along a line. specifically, White Rabbit uses 2 parameters C and D,denoting that at time x, White Rabbit is at the position(x,C*x+D).
If at some time, White Rabbit is located at one of White Cloud's lines, White Cloud will receive a message immediately.
White Rabbit has m pairs (C[i],D[i]) for i=1..m. For each i=1..m, White Cloud wants to know if White Rabbit uses (C[i],D[i]) , when is the last time White Cloud can receive a message.
输入描述:
The first line of input contains an integer n. (n<=50000) For the next n lines, the i-th line contains 2 integers A[i], B[i], describing the i-th line. (-1e9<=A[i],B[i]<=1e9) All numbers A[i] are different. The next line contains an integer m. (m<=50000) For the next m lines, the i-th line contains 2 integers C[i],D[i], describing the i-th pair.(-2e9<=C[i],D[i]<=2e9) Each C[j] is different from any of the numbers A[i]. Each D[j] is different from any of the numbers B[i].
输出描述:
Print m lines. The i-th line contains a real number with at least 6 digits after the decimal point, denoting the latest time White Cloud can receive a message. Your answer must be correct within an absolute error of 1e-6. If White Cloud can't receive any message during White Rabbit's trip,print a string "No cross".
示例1
输入
2 0 -1 1 2 3 -1 4 2 -2 2 5
输出
5.000000000000000 4.000000000000000 No cross
说明
计算几何+二分。
可以得知,对于y=ax+b,与y=cx+d,两条直线的交点的横坐标为(d-b)/(a-c)
对a和c取反之后,实际上是可以表示成两个点的斜率
我们可以存下所有的询问,然后用凸包维护。
在维护凸包的过程中用二分找到对于询问的点斜率最大的点。
#include<bits/stdc++.h>
#define mp make_pair
#define fir first
#define se second
#define ll long long
#define pb push_back
using namespace std;
const int maxn=1e5+10;
const ll mod=1e9+7;
const int maxm=1e6+10;
const double eps=1e-7;
const int inf=0x3f3f3f3f;
const double pi = acos (-1.0);
int dcmp ( double x)
{
if ( fabs (x) < eps) return 0;
return (x < 0 ? -1 : 1);
}
inline double sqr ( double x)
{
return x*x;
}
struct Point
{
double x, y;
int id;
Point ( double _x = 0, double _y = 0):x(_x), y(_y) {}
void input ()
{
scanf ( "%lf%lf", &x, &y);
}
void output ()
{
printf ( "%.2f %.2f\n", x, y);
}
bool operator == ( const Point &b) const
{
return (dcmp (x-b.x) == 0 && dcmp (y-b.y) == 0);
}
bool operator < ( const Point &b) const
{
return (dcmp (x-b.x) == 0 ? dcmp (y-b.y) < 0 : x < b.x);
}
Point operator + ( const Point &b) const
{
return Point (x+b.x, y+b.y);
}
Point operator - ( const Point &b) const
{
return Point (x-b.x, y-b.y);
}
Point operator * ( double a)
{
return Point (x*a, y*a);
}
Point operator / ( double a)
{
return Point (x/a, y/a);
}
double len2 ()
{
return sqr (x) + sqr (y);
}
double len ()
{
return sqrt (len2 ());
}
Point change_len ( double r)
{
double l = len ();
if (dcmp (l) == 0) return *this;
r /= l;
return Point (x*r, y*r);
}
Point rotate_left ()
{
return Point (-y, x);
}
Point rotate_right ()
{
return Point (y, -x);
}
Point rotate (Point p, double ang)
{
Point v = (*this)-p;
double c = cos (ang), s = sin (ang);
return Point (p.x + v.x*c - v.y*s, p.y + v.x*s + v.y*c);
}
Point normal ()
{
double l = len ();
return Point (-y/l, x/l);
}
};
double cross (Point a, Point b)
{
return a.x*b.y-a.y*b.x;
}
double cal(Point a,Point b){
return (a.y-b.y)/(a.x-b.x);
}
Point p[maxn],ch[maxn];
double ans[maxn];
int n,m;
int num;
int convex_hull (Point *p, Point *ch, int n)
{
sort (p, p+n);
int m = 0;
for ( int i = 0; i < n; i++)
{
if (p[i].id){
int l=0;
int r=m-1;
while (l<r){
int mid=(l+r)>>1;
if(cross(p[i]-ch[mid],p[i]-ch[mid+1])<=0) r=mid;
else l=mid+1;
}
if (l<m){
ans[p[i].id]=max(ans[p[i].id],cal(p[i],ch[l]));
}
continue;
}
while (m > 1 && cross (ch[m-1]-ch[m-2], p[i]-ch[m-1]) <= 0)
m--;
ch[m++] = p[i];
}
int k = m;
for ( int i = n-2; i >= 0; i--)
{
if (p[i].id){
int l=k-1;
int r=m-1;
while (l<r){
int mid=(l+r)>>1;
if(cross(p[i]-ch[mid],p[i]-ch[mid+1])<=0) r=mid;
else l=mid+1;
}
if (l<m){
ans[p[i].id]=max(ans[p[i].id],cal(p[i],ch[l]));
}
continue;
}
while (m > k && cross (ch[m-1]-ch[m-2], p[i]-ch[m-1]) <= 0)
m--;
ch[m++] = p[i];
}
if (n > 1)
m--;
return m;
}
int main(){
cin>>n;
for (int i=0;i<n;i++){
p[i].input();
p[i].x*=-1; //转化为求最大值
p[i].id=0;
}
cin>>m;
for (int i=0;i<m;i++){
p[i+n].input();
p[i+n].x*=-1; //转化为求最大值
p[i+n].id=i+1;
}
num=convex_hull(p,ch,n+m);
for (int i=1;i<=m;i++){
if (dcmp(ans[i])==0){
printf("No cross\n");
}
else printf("%.15lf\n",ans[i]);
}
return 0;
}