2020牛客暑期多校第三场 C - Operation Love(简单计算几何)

传送门


比赛时未知原因一直卡RE,卡了十几发无可奈何,虽然是方法错了,但是给我报RE我也不知道方法对不对…算了这个题还是有必要写一下,加深对叉乘的印象

首先线段长度是一定的,那么我们从起点开始依次求出每段线段的长度,记录下长度为10的线段的起点和终点,这两个起点和终点是顺时针还是逆时针得到的无需考虑,只需记住一定是起点指向终点的向量。然后就不难得到大拇指和小拇指的两个点,是在起点的前一个和终点的后一个,这两个点哪个是大拇指的点,可以求出两个线段的长度,那么短的那个就是大拇指

最后就是判断大拇指的向量是否在最长线段的左边,注意向量的方向即可

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-6;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e6+10;
 
inline int dcmp(double d){   //浮点数和0比较
    if(fabs(d)<eps) return 0;
    return d>0?1:-1;
}
 
struct Point{
    double x,y;
    Point(double a=0,double b=0):x(a),y(b){}
 
    Vector operator + (Vector B){
        return Vector(x+B.x,y+B.y);
    }
 
    Vector operator - (Point B){
        return Vector(x-B.x,y-B.y);
    }
 
    Vector operator * (double d){  //数乘
        return Vector(x*d,y*d);
    }
 
    double operator * (Vector B){  //数量积
        return x*B.x+y*B.y;
    }
 
    Vector operator / (double d){
        return Vector(x/d,y/d);
    }
 
    double operator ^ (Vector B){  //叉乘
        return x*B.y-y*B.x;
    }
 
    bool operator < (const Point &b) const {
        if(dcmp(x-b.x)==0) return y<b.y;
        return x<b.x;
    }
 
    bool operator == (const Point& b) const {
        if(dcmp(x-b.x)==0 && dcmp(y-b.y)==0)
            return true;
        return false;
    }
}p[25];
 
double sqrDis(Point a,Point b){
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
 
bool ToLeftTest(Point c,Point b,Point a){ //判断折线bc是不是向ba的逆时针方向(左边)转向
    return ((a-b)^(c-b)) > 0;
}
 
struct Line{
    int i,j;
    double len;
 
    bool operator < (const Line &p) const{
        return len<p.len;
    }
};
 
bool vis[30];
vector<Line> vec;
 
 
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<20;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        int cur=0;
        double maxd=0.0;
        for(int i=0;i<20;i++){
            double len=round(sqrDis(p[i],p[(i+1)%20]));
            if(dcmp(len-maxd)>0) cur=i,maxd=len;
        }
        int l=cur,r=(cur+1)%20,pos;
        int L=(l-1+20)%20,R=(r+1)%20;
        double d1=round(sqrDis(p[l],p[L])),d2=round(sqrDis(p[r],p[R]));
        bool flag=0;
        if(dcmp(d1-d2)>0){
            if(ToLeftTest(p[R],p[r],p[l])) puts("right");
            else puts("left");
        }else{
            if(ToLeftTest(p[L],p[l],p[r])) puts("right");
            else puts("left");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44691917/article/details/107494394