BZOJ 3800 Saber VS Lancer/POJ 1755 Triathlon 半平面交

來源:互聯網
上載者:User

標籤:bzoj   poj   半平面交   線性規劃   卡精度   

題目大意:有n個人進行鐵人三項比賽,對於這三種運動,每個人都有一個固定的速度,但是每種運動的長度是多少並不知道。現在問裁判可不可以通過調整這三項運動的長度來使某一個人贏得比賽。


思路:考慮現在我們想讓一個人贏的時候,這個人的三個速度分別為v1,v2,v3,想讓所有人都輸給他,設某一個人的三個速度是v1‘,v2‘,v3‘。設三項的比賽的長度為l1,l2,l3。那麼不難得到如下方程:l1 / v1 + l2 / v2 + l3 / v3 < l1 / v1‘ + l2 / v2‘ + l3 / v3‘。

但是這個方程有三個未知數,這是啥,根本沒法處理。其實這個題只要求我們求出能否有解,那麼對於具體的值我們並不關注。如果一個解X,Y,Z可以讓一個人贏所有的人,那麼X*K,Y*K,Z*K也可以讓這個人贏所有的人。所以我們確定一個l值並不會影響答案的正確性。所以假設l3 = 1,那麼l3 / v3和l3 / v3‘就是兩個定值了。

原方程就變成了:(為了方便理解,設x = l1,y = l2)x * (v1‘ - v1) / (v1 * v1‘) + y * (v2‘ - v2) / (v2 * v2‘) + k - k‘ < 0.

這個式子中,我們只有xy不知道,剩下的都是常量。這就是一個關於x和y的一個半平面。找到所有的半平面,然後判斷核心是否存在,就是答案。

資料範圍很小,用O(n^2)的半平面交應該也可以過。

然而我並沒有過這個題。。這個題卡精度簡直令人不忍直視,從網上搞到資料之後用cena測,一共25個點,就是有兩個點死活過不去。。心裡AC了。。


CODE(未AC,謹慎提交):


#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 10010#define EPS 1e-16#define INF (1ll << 32)using namespace std;#define DCMP(a) (fabs(a) < EPS)  struct Complex{    double v1,v2,v3;          void Read() {        scanf("%lf%lf%lf",&v1,&v2,&v3);    }}src[MAX];  struct Point{    double x,y;          Point(double _ = .0,double __ = .0):x(_),y(__) {}    Point operator +(const Point &a)const {        return Point(x + a.x,y + a.y);    }    Point operator -(const Point &a)const {        return Point(x - a.x,y - a.y);    }    Point operator *(double a)const {        return Point(x * a,y * a);    }}p[MAX];  struct Line{    Point p,v;    double alpha;          bool operator <(const Line &a)const {        return alpha < a.alpha;    }    Line(Point _,Point __):p(_),v(__) {        alpha = atan2(v.y,v.x);    }    Line() {}}line[MAX],q[MAX];  int cnt,lines;  inline double Cross(const Point &a,const Point &b){    return a.x * b.y - a.y * b.x;}  inline bool OnLeft(const Line &l,const Point &p){    return Cross(l.v,p - l.p) > 0;}  inline void MakeLine(const Complex &win,const Complex &lose){    double A = (lose.v1 - win.v1) / (win.v1 * lose.v1);    double B = (lose.v2 - win.v2) / (win.v2 * lose.v2);    double C = (lose.v3 - win.v3) / (win.v3 * lose.v3);    if(DCMP(A) && DCMP(B) && C < EPS)        throw false;    if(DCMP(B)) B = EPS;    line[++lines] = Line(Point(.0,-C / B),Point(-B,A));}  inline void Initialize(){    line[++lines] = Line(Point(0,0),Point(1,0));    line[++lines] = Line(Point(INF,0),Point(0,1));    line[++lines] = Line(Point(INF,INF),Point(-1,0));    line[++lines] = Line(Point(0,INF),Point(0,-1)); }  inline Point GetIntersection(const Line &a,const Line &b){    Point u = a.p - b.p;    double temp = Cross(b.v,u) / Cross(a.v,b.v);    return a.p + a.v * temp;}  inline bool HalfplaneIntersection(){    int front = 1,tail = 1;    q[1] = line[1];    for(int i = 2;i <= lines; ++i) {        while(front < tail && !OnLeft(line[i],p[tail - 1]))  --tail;        while(front < tail && !OnLeft(line[i],p[front])) ++front;        if(DCMP(Cross(line[i].v,q[tail].v)))            q[tail] = OnLeft(q[tail],line[i].p) ? line[i]:q[tail];        else    q[++tail] = line[i];        if(front < tail) p[tail - 1] = GetIntersection(q[tail],q[tail - 1]);    }    while(front < tail && !OnLeft(q[front],p[tail - 1])) --tail;    if(tail - front <= 1)    return false;    double re = Cross(tail,front);    for(int i = front; i < tail; ++i)        re += Cross(p[i],p[i + 1]);    return !DCMP(re);}  int main(){    cin >> cnt;    for(int i = 1; i <= cnt; ++i)        src[i].Read();    for(int i = 1; i <= cnt; ++i) {        lines = 0;        try{            for(int j = 1; j <= cnt; ++j) {                if(i == j)  continue;                MakeLine(src[i],src[j]);            }        }        catch(bool flag) {            puts("No");            continue;        }        Initialize();        sort(line + 1,line + lines + 1);        if(HalfplaneIntersection()) puts("Yes");        else    puts("No");    }    return 0;}


BZOJ 3800 Saber VS Lancer/POJ 1755 Triathlon 半平面交

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.