三角形花园和向左走(三角形性质和点集排序)

三角形花园(Triangular garden)
题意:

给定一个三角形的三个点的坐标,和三角形内的一个点,如果这个点位于三角形的重心,垂心,内心或者外心上,那么就输出Yes,否则输出No。

分析:

首先需要知道这几点心的特点和性质:

  • 垂心:三角形的三条高线的交点叫做三角形的垂心

  • 重心的几条性质:
    1、重心到顶点的距离与重心到对边中点的距离之比为2:1。
    2、重心和三角形3 个顶点组成的3 个三角形面积相等。
    3、重心到三角形3 个顶点距离的平方和最小。

  • 内心:三角形的三条内角平分线交于一点。该点叫做三角形的内心。
    三角形的内心即三角形内切圆的圆心。
    内心定理:三角形的三内角平分线交于一点。该点叫做三角形的内心。

  • 外心:三角形的外心是三边中垂线的交点,且这点到三角形三顶点的距离相等。

代码:
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-7;
struct Point{
    double x,y;
    Point(double _x = 0, double _y=0):x(_x),y(_y){}
    Point operator* (const double &a){
        return Point(x * a, y * a);
    }
    Point operator+(const Point &a)
    {
        return Point(x + a.x, y + a.y);
    }
    bool operator==(const Point &a){
        return fabs(x - a.x)<eps && fabs(y-a.y)<eps;
    }Point operator-(const Point &a){
        return Point(x - a.x, y - a.y);
    }
    double operator*(const Point &a){
        return x * a.x + y * a.y;
    }
}zero=Point(0,0),O,A,B,C;
double dis(const Point &b,const Point &a){
    return sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
}
int main()
{
    scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y,&O.x,&O.y);
    if( O-A+O-B+O-C==zero ||
    ( fabs(((O-A)*(O-B))-((O-A)*(O-C)))<eps && fabs(((O-A)*(O-C))-((O-B)*(O-C)))<eps ) ||
    (O-A)*dis(B,C)+(O-B)*dis(A,C)+(O-C)*dis(A,B)==zero ||
    (fabs(dis(O,A)-dis(O,B))<eps && fabs(dis(O,B)-dis(O,C))<eps) )
        printf("Yes\n");
    else
        printf("No\n");
    return 0;
}

向左走

题意:

给定一些点,以纵坐标最小的点(纵坐标相同取横坐标最小)为起点,向其他点连边,需要满足以下条件:

1.只能向左转

2.只能走直线

3.不能走已经走过的点

怎么样走才能经过最多点。

样例:

4
1 3 1
2 7 1
3 5 3
4 5 5

输出:1 2 4 3 (id)

思路:

1.输入数据的同时先找到起点

2.遍历所有的点,用冒泡排序给给点排序

  • 排序的条件就是i+2点必须在i-i+1直线的右边。
  • 如果直线(i,i+2)在直线(i,i+1)的坐标或者在直线上(不包含端点就要交换)

3.输出排好序的点。

代码:
#include <iostream>
#include <cmath>

using namespace std;

const int N=1010;

struct Point 
{
	int id,x,y;
	
}p[N];

int cross(Point a,Point b,Point c)
{
	return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}

int dist(Point a,Point b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

bool check(Point a,Point b,Point c)
{
	if(cross(a,b,c)>0 || (cross(a,b,c)==0 && dist(a,c)<dist(b,c)))
		return true;
	return false;
}

int main()
{
	int n;
	while(scanf("%d",&n)!=-1)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d%d%d",&p[i].id,&p[i].x,&p[i].y);
			if(p[i].y<p[0].y || (p[i].y==p[0].y && p[i].x<p[0].x)) swap(p[i],p[0]);
		}
		
		for(int i=0;i<n;i++)
		{
			for(int j=i+2;j<n;j++)
			{
				if(check(p[j],p[i+1],p[i])) swap(p[j],p[i+1]);
			}
		}
		
		for(int i=0;i<n-1;i++) printf("%d ",p[i].id);
		printf("%d\n",p[n-1].id);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值