UVA1421 Archery

链接

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4167

题解

这道题目数据有误!
根据我的推测,这道题的数据组数很可能小于 T ,如果你使用读入优化,可能会不断的读到 c = 1 ,然后陷入死循环
最后我在读入优化中加入了 c ! = 1 的判断,才 A 掉这道题目(这里干耗了2个小时!
做法很简单, O ( n 2 ) 枚举每两条线段,然后利用端点求一下射中这两条线段在 y = 0 上应该站在那个区间,然后所有的区间求个交集,如果交集为空,则输出 N O 否则 Y E S

代码

//几何题
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#define maxn 6000
#define eps 1e-8
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
double L, R;
struct segment{double d, l, r;}seg[maxn];
int n, W;
bool cmp(segment &a, segment &b){return a.d>b.d;}
double calc(double x1, double y1, double x2, double y2)
{
    if(fabs(y1-y2)<eps)return x1;
    return x1-(x1-x2)*y1/(y1-y2);
}
int read(int x=0)
{
    char c, f=1;
    for(c=getchar();!isdigit(c) and c^-1;c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
    return f*x;
}
bool solve()
{
    int i, j;
    L=0, R=W;
    for(i=1;i<=n and L<R+eps;i++)for(j=i+1;j<=n and L<R+eps;j++)
    {
        L=max(L,calc(seg[i].r,seg[i].d,seg[j].l,seg[j].d));
        R=min(R,calc(seg[i].l,seg[i].d,seg[j].r,seg[j].d));
    }
    return L<R+eps;
}
int main()
{
    int T;
    for(T=read();T--;)
    {
        W=read(), n=read();
        for(int i=1;i<=n;i++)seg[i].d=read(), seg[i].l=read(), seg[i].r=read();
        sort(seg+1,seg+n+1,cmp);
        if(solve())printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/81172665