codeforces 849B

codeforces 849B

B. Tell Your World

introduction

判断是否存在两条线,使得所有的点都落在这两条线上,并且每条线上至少有一个点

method

先取三个点,两两之间连线,则如果满足要求,三条线必有一条是结果中的直线。剩下的工作就是判断剩下的点是否在这条直线上,或者到直线的距离与第三个点到直线的距离相等,并且在同侧

useful knowledge

  • 判断两个浮点数是否相等的方法是,将两个浮点数做差取绝对值,与预设的精度比较,例如

    eps=1e-7
    fabs(a-b)>1e-7

    如果为True,那么a大于b
    为什么要这么做?

  • 直线表达成乘法的形式,可以避免引入浮点数

tips

  • 只有在求点线距离的时候使用浮点数,其余时候使用long long
  • 使用浮点数有很多问题,在可以使用整数的情况下优先使用整数

AC code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<cassert>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
typedef long long ll;
using namespace std;
const int MAXN=1e3+10;
const double eps=1e-7;
int n;
ll ycod[MAXN];
struct line{
    ll A,B,C;
    line(){}
    line(ll x1,ll y1,ll x2,ll y2)
    {
        A=(y1-y2);
        B=-(x1-x2);
        C=y1*(x1-x2)-(y1-y2)*x1;
    }
    double dist(ll x,ll y)
    {
        return fabs(A*x+B*y+C)*1.0/(sqrt(A*A*1.0+B*B*1.0));
    }
    bool online(ll x,ll y)
    {
        return (A*x+B*y+C)==0;
    }
    bool sameside(ll x1,ll y1,ll x2,ll y2)
    {
        ll r1=A*x1+B*y1+C,
        r2=A*x2+B*y2+C;
        bool rt= (r1>0&&r2>0)||(r1<0&&r2<0);
//        if(n==20)assert(rt==true);
        return rt;
    }
};
bool judge(line &l,ll idx)
{
    double d=l.dist(idx,ycod[idx]);
    for(int i=4;i<=n ;i++ ){
        if(l.online(i,ycod[i]))continue;
        if(!l.sameside(idx,ycod[idx],i,ycod[i]))return false;
        double td=l.dist(i,ycod[i]);
        if(fabs(td-d)>eps)return false;
    }
    return true;
}
int main()
{
//    freopen("in.txt","r",stdin);
    cin>>n;
    for(int i=1;i<=n ;i++ ){
        cin>>ycod[i];
    }
    bool ok;
    if(n==3){
        line l1=line(1,ycod[1],2,ycod[2]);
        ok =!l1.online(3,ycod[3]);
    }
    else {
        line l1=line(1,ycod[1],2,ycod[2]);
        line l2=line(2,ycod[2],3,ycod[3]);
        line l3=line(1,ycod[1],3,ycod[3]);
        if(l1.online(3,ycod[3])==false)
            ok =judge(l1,3)||judge(l2,1)||judge(l3,2);
        else {
            double d=-1;
            int idx=-1;
            ok=true;
            for(ll i=4;i<=n ;i++ ){
                if(l1.online(i,ycod[i]))continue;
                int td=l1.dist(i,ycod[i]);
                if(d==-1)d=td,idx=i;
                else {
                    if(l1.sameside(idx,ycod[idx],i,ycod[i])==false){
                            ok=false;
                            break;
                    }
                    else if(abs(d-td)>eps){
                            ok=false;
                            break;
                    }
                }
            }
            if(idx==-1)ok=false;
        }
    }
    if(ok)cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
}

原文地址:https://www.cnblogs.com/MalcolmMeng/p/10141891.html