Triangle ~~ 叉積

題目超鏈接

One day, ABC and DD found a triangular wheat field, and they decide to cut it into two pieces with the same area with a segment. Because of various reasons, one of the endpoints of the division line is fixed at (px,py). Now you are asked to find the other endpoint of the segment.
If the given endpoint does not lie on the boundary of the wheat field, the problem should be regarded as invalid. The other endpoint required should also locate on the boundary.

Input

The input provides several test cases and the first line of the input contains a single integer T (1≤T≤1000000) indicating the number of cases.
For each test case, eight integers x1​,y1​,x2​,y2​,x3​,y3​,px​ and py are given in a line, where (x1,y1),(x2,y2) and (x3,y3)describe the coordinates of vertices for the given triangle wheat field which are guaranteed to be not colinear, and (px,py) is the given endpont of the segment. All coordinates are integers in the range [0,100000].

Output

For each test case, output the coordinate of the other endpoint of the division segment, or output the number -1 if the problem, in this case, is invalid.
Formally, if your answer is aaa and the jury’s answer is bbb, then your answer will be considered correct if and only if 在這裏插入圖片描述

本題答案不唯一,符合要求的答案均正確
樣例輸入

2
0 0 1 1 1 0 1 0
0 0 1 1 1 0 2 0

樣例輸出

0.500000000000 0.500000000000
-1

題意:給你三角形的三個頂點,再給你一個點,若該點在三角形上,則再在這個三角形上找一點,連接着兩個點使得三角形被分成面積相等的兩半。否則輸出-1。
思路:我們只討論詢問點在三角形上的情況,首先確定詢問點在哪條邊上,再確定答案點在哪條邊上。(都是通過叉積判斷的),具體實現看代碼:

#include<bits/stdc++.h>
#define eps 1e-8
#define zero(x) (!(((x)>0?(x):-(x))<eps)) // x = 0 返回 false

using namespace std;
struct point {double x, y; point(){} point(double x, double y): x(x), y(y){}};

double cross(point a, point b, point c) {
  return fabs((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
}

void solve(point a, point b, point c, point d, double S) {
  double k = S / cross(b, d, c); // S = cross(kcb * db)
  printf("%.12f %.12f\n",(c.x-b.x)*k + b.x, (c.y-b.y)*k + b.y);
}

int main() {
  int T; scanf("%d", &T);
  while(T --) {
    point a, b, c, d;
    scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
    double S=cross(a,b,c),s1=cross(d,a,b),s2=cross(d,b,c),s3=cross(d,c,a);
    if ((zero(S-s1-s2-s3))||zero(s1)&&zero(s2)&&zero(s3)) printf("-1\n");
    else if (!zero(s1)) {if (s2>s3) solve(a,b,c,d,S/2); else solve(b,a,c,d,S/2);}
    else if (!zero(s2)) {if (s1>s3) solve(c,b,a,d,S/2); else solve(b,c,a,d,S/2);}
    else if (!zero(s3)) {if (s1>s2) solve(c,a,b,d,S/2); else solve(a,c,b,d,S/2);}
  }
  return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章