洛谷P1355 神秘大三角

本文介绍了一种算法,用于判断一个点是否位于由三个顶点定义的三角形内部、外部还是边界上。通过计算叉积来确定点与三角形的关系,并提供了完整的Pascal代码实现。

神秘大三角

题目描述

判断一个点与已知三角形的位置关系。

输入输出格式

输入格式:

前三行:每行一个坐标,表示该三角形的三个顶点

第四行:一个点的坐标,试判断该点与前三个点围成三角形的位置关系

(详见样例)

所有坐标值均为整数。

输出格式:

若点在三角形内(不含边界),输出1;

若点在三角形外(不含边界),输出2;

若点在三角形边界上(不含顶点),输出3;

若点在三角形顶点上,输出4。

分析:顶点直接判断,然后算出三条边关于这个点的叉积m,如果m正负性相同说明这个点在三角形内,m=0说明此点在三角形边界上,m正负性不同说明这个点在三角形外。

代码

var
  x1,x2,x3,y1,y2,y3,p1,p2,xi,yi:longint;
  s1,s2,s4,s3:string;


procedure change;
var
  i,j:longint;
  st:string;
begin
  st:='';
  i:=2;
  while s1[i] in ['0'..'9'] do
    begin
      st:=st+s1[i];
      inc(i);
    end;
  inc(i);
  val(st,x1);
  st:='';
  while s1[i] in ['0'..'9'] do
    begin
      st:=st+s1[i];
      inc(i);
    end;
  i:=2;
  val(st,y1);
  st:='';
  while s2[i] in ['0'..'9'] do
    begin
      st:=st+s2[i];
      inc(i);
    end;
  inc(i);
  val(st,x2);
  st:='';
  while s2[i] in ['0'..'9'] do
    begin
      st:=st+s2[i];
      inc(i);
    end;
  i:=2;
  val(st,y2);
  st:='';
  while s3[i] in ['0'..'9'] do
    begin
      st:=st+s3[i];
      inc(i);
    end;
  inc(i);
  val(st,x3);
  st:='';
  while s3[i] in ['0'..'9'] do
    begin
      st:=st+s3[i];
      inc(i);
    end;
  i:=2;
  val(st,y3);
  st:='';
  while s4[i] in ['0'..'9'] do
    begin
      st:=st+s4[i];
      inc(i);
    end;
  inc(i);
  val(st,xi);
  st:='';
  while s4[i] in ['0'..'9'] do
    begin
      st:=st+s4[i];
      inc(i);
    end;
  i:=2;
  val(st,yi);
  st:='';
end;


function find(x1,y1,x2,y2:longint):longint;
begin
  find:=(x1-xi)*(y2-yi)-(x2-xi)*(y1-yi);
end;


begin
  readln(s1);
  readln(s2);
  readln(s3);
  readln(s4);
  change;
  if ((xi=x1) and (yi=y1)) or ((xi=x2) and (yi=y2)) or ((xi=x3) and (yi=y3))
    then begin
           writeln(4);
           halt;
         end;
  p1:=find(x1,y1,x2,y2);
  if p1=0 then
    begin
      writeln(3);
      halt;
    end;
  p2:=p1;
  p1:=find(x2,y2,x3,y3);
  if p1=0 then
    begin
      writeln(3);
      halt;
    end;
  if ((p1>0) and (p2<0)) or ((p1<0) and (p2>0)) then
    begin
      writeln(2);
      halt;
    end;
  p1:=find(x3,y3,x1,y1);
  if p1=0 then
    begin
      writeln(3);
      halt;
    end;
  if ((p1>0) and (p2<0)) or ((p1<0) and (p2>0)) then
    begin
      writeln(2);
      halt;
    end;
  writeln(1);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值