nyoj487点数

点数

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
在一个二维的坐标系内有三个点,这三个点构成一个三角形,请你求出这个三角形内部和边界上的坐标点一共有多少个。
输入
输入三个整数点,坐标x,y均为1~99的整数。注意:程序以文件结束符“EOF”结束输入。
输出
按要求输出点的个数,每个点占一行.
样例输入
0 0 0 1 3 0
0 0 2 0 0 2
样例输出
5
6

我的思路:设三角形三点为a,b,c,待检测点为d。
若满足:d和c在过ab的直线的同一侧,且d和a在过bc的直线的同一侧,且d和b在过ac的直线的同一侧。
或 在三边的任意一边上

测试数据来几发
0 0 1 1 2 2
8 2 9 1 3 5
7 9 3 1 9 8
答案
3
4
14

丑陋的AC代码
#include <stdio.h>
#include <math.h>
struct point{
	double x,y;
}p[3];
int onLine(point A[],double Dx, double Dy) {
	double k, b, tCy, tDy, tx, ty;
	for(int i = 0; i < 3; i++) {
		tx = A[i].x-A[(i+1)%3].x;
		ty = A[i].y-A[(i+1)%3].y;
		k = ty / tx;
		b = A[i].y - k*A[i].x;
		tDy = k*Dx + b;
		if(fabs(fabs(A[i].x-Dx)+fabs(A[(i+1)%3].x-Dx)-fabs(tx))<1e-6&&fabs(fabs(A[i].y-Dy)+fabs(A[(i+1)%3].y-Dy)-fabs(ty))<1e-6)
		if((fabs(A[i].x-A[(i+1)%3].x)<1e-6&&fabs(A[i].x-Dx)<1e-6)||(fabs(A[i].y-A[(i+1)%3].y)<1e-6&&fabs(A[i].y-Dy)<1e-6)||(fabs(tDy-Dy)<1e-6)) {
			return 1;//在三边的任意一边上就符合 
		}
	}
	return 0;
}
int getfg(point A, point B,point C,double Dx, double Dy) {
	int f1, f2;
	double k, b, tCy, tDy;
	k = (A.y-B.y) / (A.x-B.x);
	b = A.y - k*A.x;
	tCy = k*C.x + b;
	tDy = k*Dx + b;
	if(fabs(A.x - B.x) < 1e-6) {
		if(C.x < A.x) f1 = -1;
		else if(C.x > A.x) f1 = 1;
		else f1 = 0;
		if(Dx < A.x) f2 = -1;
		else if(Dx > A.x) f2 = 1;
	} else if(fabs(k-0) < 1e-6) {
		if(C.y < A.y) f1 = -1;
		else if(C.y > A.y) f1 = 1;
		else f1 = 0;
		if(Dy < A.y) f2 = -1;
		else if(Dy > A.y )f2 = 1;
	} else {
		if(C.y > tCy) f1 = -1;
		else if(C.y < tCy)f1 = 1;
		else f1 = 0;
		if(Dy > tDy) f2 = -1;
		else if(Dy < tDy) f2 = 1;
	}
	if(f1*f2 > 0) return 1;//表示同侧
	else return 0;
}
int main() {
	double minX, maxX, minY, maxY;
	int i, j;
	while(~scanf("%lf%lf", &p[0].x, &p[0].y)) {
		int count = 0;
		maxX = p[0].x, maxY = p[0].y;
		minX = maxX, minY = maxY;
		for(i = 1; i < 3; i++) {
			scanf("%lf%lf", &p[i].x, &p[i].y);
			if(p[i].x > maxX) maxX = p[i].x;
			if(p[i].x < minX) minX = p[i].x;
			if(p[i].y > maxY) maxY = p[i].y;
			if(p[i].y < minY) minY = p[i].y;
		}//用外包最小矩形的方法缩小要查找的范围 
		for(i = minX; i <= maxX; i++) {
			for(j = minY; j <= maxY; j++) {
				if(onLine(p,i,j)||getfg(p[0],p[1],p[2],i,j) && getfg(p[1],p[2],p[0],i,j) && getfg(p[0],p[2],p[1],i,j)) {
					
					count++;
				}
			}
		}
		printf("%d\n", count);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值