[洛谷P1766]液体滴落

来源:互联网 发布:mac本和win本 编辑:程序博客网 时间:2024/04/28 20:49

题目←

首先需明确题目中“不受影响”的含义
出现两条相交线段的话,液体的运行轨迹应该是这样的:

这里写图片描述

于是发现只需要确定液体从一条线段上落下来后首先落到哪条线段上就可以确定下一个落点了……
然后?按每条线段较低端点的降序排列->保证液体不会落到之前的线段上;
然后模拟就可以了
注意细节

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 100000 + 50;struct edge{    double x1,y1,x2,y2;    double k,b;}l[MAXN];int n;double s;bool cmp(edge a,edge b){    return min(a.y1,a.y2) > min(b.y1,b.y2);}int p = 1;bool in(int num,int pos){    if(l[num].x1 < pos && l[num].x2 > pos)return true;    return false;}double pre;int main(){    scanf("%d%lf",&n,&s);    for(int i = 1;i <= n;i ++){        scanf("%lf%lf%lf%lf",&l[i].x1,&l[i].y1,&l[i].x2,&l[i].y2);        if(l[i].x1 > l[i].x2){            swap(l[i].x1,l[i].x2);            swap(l[i].y1,l[i].y2);        }        l[i].k = (l[i].y2 - l[i].y1)/(l[i].x2 - l[i].x1);        l[i].b = l[i].y2 - l[i].k*l[i].x2;     }    sort(l + 1,l + n + 1,cmp);    pre = 2147483647;    while(p <= n){        while((!in(p,s) || l[p].k*s + l[p].b >= pre) && p <= n)            p ++;        if(p > n)break;        double h = l[p].k*s + l[p].b;        for(int i = p + 1;i <= n;i ++){            if(in(i,s)){                if(l[i].k*s + l[i].b > h && l[i].k*s + l[i].b < pre){//                    h = l[i].k*s + l[i].b;                    p = i;                }            }        }        s = l[p].y1 < l[p].y2 ? l[p].x1:l[p].x2;        pre = l[p].y1 < l[p].y2 ? l[p].y1:l[p].y2;        p ++;    }    int ans = s;    printf("%d",ans);    return 0;}

今后还是多在洛谷刷题吧
毕竟有AC数这个东西……避免把代码一糊就往上交Orz

原创粉丝点击