UVa 10112 - Myacm Triangles

传送门UVa 10112 - Myacm Triangles

总算让我做出一题了.

题目前面都在扯蛋, 我还看了半天

题意是给出几个点, 让我们找出一个面积最大且内部(包括边界)没有点的三角形.

想不出更好的办法, 只好枚举了.

我的思路是先计算面积是否大于当前的最大面积, 如果是, 再判断他的内部有没有点. 如果没有, 记录顶点.

注意计算面积的时候要取绝对值,被这里坑了一次

判断一个点是否在一个三角形中, 我采用的是叉乘法.


详情请点这里.

叉乘法判断点是否在三角形内


详情见代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

using namespace std;

struct point
{
    char name;
    int x, y;
};

double CalcuS(int i, int j, int k);
bool Judge(int x, int i, int j, int k);
void Record(int i, int j, int k);

int comp(const void *_a, const void *_b)
{
    char *a = (char *)_a;
    char *b = (char *)_b;
    return *a - *b;
}

point dian[50];
char temp[10];

int main()
{
    //freopen("input.txt", "r", stdin);
    int n;
    int i, j, k, l;
    double S, Smax;
    while (scanf("%d", &n))
    {
        memset(temp, 0, sizeof(temp));
        memset(dian, 0, sizeof(dian));
        getchar();
        if (n == 0)
            break;
        for (i = 0; i < n; i++)
        {
            scanf("%c%d%d", &dian[i].name, &dian[i].x, &dian[i].y);
            getchar();
        }
        Smax = -1;
        for (i = 0; i < n; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                for (k = j + 1; k < n; k++)
                {
                    S = CalcuS(i, j, k);
                    if (S <= Smax || S == 0)
                        continue;
                    else
                    {
                        for (l = 0; l < n; l++)     //扫描除了三点以外的所有的点
                        {
                            if (l == i || l == j || l == k) //如果是现在的点就跳过.
                                continue;
                            if (Judge(l, i, j, k) == true)  //如果有点在这三点里面, 不符合要求.
                                break;
                        }
                        if (l == n)     //符合要求的, 记录字母, 和最大面积
                        {
                            Smax = S;
                            Record(i, j, k);
                        }
                    }
                }
            }
        }
        qsort(temp, 3, sizeof(temp[0]), comp);  //排序
        printf("%s\n", temp);
    }
    return 0;
}

void Record(int i, int j, int k)
{
    temp[0] = dian[i].name;
    temp[1] = dian[j].name;
    temp[2] = dian[k].name;
}

double CalcuS(int i, int j, int k)
{
     return 0.5 * fabs(((dian[k].y - dian[i].y) * (dian[j].x - dian[i].x) - (dian[j].y - dian[i].y) * (dian[k].x - dian[i].x)));
}

bool Judge(int M, int i, int j, int k)
{
    int a, b, c;
    int x = dian[M].x;
    int y = dian[M].y;
    point MA, MB, MC;
    MA.x = dian[i].x - x;
    MA.y = dian[i].y - y;
    MB.x = dian[j].x - x;
    MB.y = dian[j].y - y;
    MC.x = dian[k].x - x;
    MC.y = dian[k].y - y;
    a = MA.x * MB.y - MB.x * MA.y;
    b = MB.x * MC.y - MC.x * MB.y;
    c = MC.x * MA.y - MA.x * MC.y;
    if (a >= 0 && b >= 0 && c >= 0 || a <= 0 && b <= 0 && c <= 0)
        return true;
    else
        return false;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值