[ZOJ1123] Triangle Encapsulation

本文介绍了一种通过枚举法寻找并打印出给定三角形内部所有整数坐标的算法实现。该算法首先确定三角形的边界范围,然后在该范围内遍历每个点,使用夹角和的方法判断其是否位于三角形内部。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

顺时针给出一个三角形的三个顶点,按照题中格式打印出所有三角形内(边上的不算)的整数坐标点。

解题思路:

枚举坐标范围内左右的点,计算点对三角形每条边两个顶点的夹角(若对某条边两个顶点的夹角为PI,则在边上),求夹角和,若夹角和为2*PI,则点在三角形内。

注意点:

Sample Output里的Program 4 by team X和End of program 4 by team X要打印。

源代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 30

const double PI=acos(-1.0), EPS=1e-6, PI2=2*acos(-1.0);

int x[4], y[4];

double dbcmp(double a, double b)
{
    return b-a>EPS?-1:a-b>EPS;
}

double radian(int ax, int ay, int bx, int by)
{
    double r=atan2(1.0*ax*by-(ay*bx), 1.0*ax*bx+(ay*by));
    return r;
}

bool in_tri(const int xx, const int yy)
{
    double s=0, t=0;
    for (int i=0; i<3; i++)
    {
        t=radian(x[i+1]-xx, y[i+1]-yy, x[i]-xx, y[i]-yy);
        if (dbcmp(t, PI)==0) return false;
        s+=t;
    }
    if (dbcmp(s, PI2)==0) return true;
    return false;
}

int min(int xx, int yy){if (xx<yy) return xx; return yy;}
int max(int xx, int yy){if (xx>yy) return xx; return yy;}

int main()
{
//    freopen("test.txt", "r", stdin);
//    freopen("ans.txt", "w", stdout);
    printf("Program 4 by team X\n");
    int  minx, maxx, miny, maxy, ansminx;
    int end_x[maxn];            //last dot in line i end with (end_x[i], i)
    bool ans[maxn][maxn];
    while (scanf("%d%d%d%d%d%d", &x[0],&y[0],&x[1],&y[1],&x[2],&y[2])==6)
    { 
        memset(ans, 0, sizeof(ans));
        memset(end_x, 255, sizeof(end_x));
        minx=miny=maxn+1;
        maxx=maxy=-1;
        for (int i=0; i<3; i++)
        {
            x[i]+=10; y[i]+=10;
            minx=min(minx, x[i]); maxx=max(maxx, x[i]);
            miny=min(miny, y[i]); maxy=max(maxy, y[i]);
        }
        x[3]=x[0]; y[3]=y[0]; ansminx=maxn+1;
        for (int xx=minx; xx<=maxx; xx++)
            for (int yy=miny; yy<=maxy; yy++)
                if (in_tri(xx,yy)){
                    ans[xx][yy]=1;
                    if (end_x[yy]==-1 || xx>end_x[yy]) end_x[yy]=xx;
                    ansminx=min(xx, ansminx);
                }
        for (int yy=maxy; yy>=0; yy--)
            if (end_x[yy]!=-1)
            {
                for (int xx=ansminx; xx<end_x[yy]; xx++)
                    if (ans[xx][yy]) printf("(%2d, %2d) ", xx-10, yy-10);
                    else printf("         ");
                if (ans[end_x[yy]][yy]) printf("(%2d, %2d)\n", end_x[yy]-10, yy-10);
            }
        printf("\n");
    }
    printf("End of program 4 by team X\n");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值