题目链接: https://ac.nowcoder.com/acm/contest/5668/C
题意:给了右手手掌的形状,然后给你20个连续的点(可顺可逆),问是左手还是右手
题解:
寻找最长边的那俩个点,和紧挨它的短的那条边的点,共三个点,求叉积判断左右手
1 #include<iostream> 2 using namespace std; 3 4 const int N = 30; 5 double x[N], y[N]; 6 7 double cal(double x1, double y1, double x2, double y2) { //计算俩点距离的平方 8 return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); 9 } 10 11 int main() { 12 int t; 13 scanf("%d", & t); 14 while (t--) { 15 for (int i = 1; i <= 20; i++) { 16 scanf("%lf %lf", &x[i], &y[i]); 17 } 18 x[0] = x[20], y[0] = y[20]; 19 x[21] = x[1], y[21] = y[1]; 20 x[22] = x[2], y[22] = y[2]; //若不懂这三行,且先别急,看完33-39就明白了 21 22 double max_len = -1; 23 24 int pos1 = 0, pos2 = 0; //存最长边10的俩个端点 25 for (int i = 1; i <= 20; i++) { 26 double temp = cal(x[i], y[i], x[i+1], y[i+1]); 27 if (max_len < temp) { 28 max_len = temp; 29 pos1 = i, pos2 = i+1; //记录下最长边的俩端 30 } 31 } 32 33 int l, mid, r; 34 if (cal(x[pos1], y[pos1], x[pos1 - 1], y[pos1 -1]) < cal(x[pos2], y[pos2], x[pos2+1], y[pos2+1])) { 35 l = pos1 - 1, mid = pos1, r = pos2; 36 } 37 else { 38 l = pos2 + 1, mid = pos2, r = pos1; 39 } 40 41 if (((x[r] - x[mid]) * (y[l] -y[mid]) - (x[l] - x[mid]) * (y[r] - y[mid])) < 0) { 42 printf("left "); 43 } 44 else { 45 printf("right "); 46 } 47 } 48 49 return 0; 50 }