天梯赛_L3-006 迎风一刀斩(数学规律)

团体程序设计天梯赛

L3-006 迎风一刀斩

一道头大的数学规律题。参考[计算几何][找规律]迎风一刀斩 PTA L3-006

判定条件:一是顶点个数,二是直角边数,三是斜边长度;除此之外,还有几种特殊情况需要判断:两矩形,两直角腰长不同的梯形,后者比较难想到。

#include <bits/stdc++.h>
using namespace std;
bool judgeVertex(int k1, int k2){    // 判断顶点数是否符合要求
    if(k1 == 3 && (k2 == 3 || k2 == 4 || k2 == 5)) return true;
    else if(k1 == 4 && (k2 == 3 || k2 == 4)) return true;
    else if(k1 == 5 && k2 == 3) return true;
    else return false;
}
bool judgeRAVert(int k, int* x, int* y, int& hypo){    // 判断直角边数是否符合要求,并找到斜边
    int cnt = 0;
    for(int i = 0; i <= k - 1; i++){
        int j = (i + 1) % k;
        if((x[i] == x[j]) || (y[i] == y[j])) cnt++;
        else hypo = i;    // 斜边:i-j
    }
    if(k == 5 && cnt == 4) return true;
    else if(k == 4 && (cnt == 3 || cnt == 4)) return true;
    else if(k == 3 && cnt == 2) return true;
    else return false;
}
bool judgeHypo(int k1, int* x1, int* y1, int hypo1, int k2, int* x2, int* y2, int hypo2){    // 判断斜边长是否相等
    int len1 = pow((x1[hypo1] - x1[(hypo1 + 1) % k1]), 2) + pow((y1[hypo1] - y1[(hypo1 + 1) % k1]), 2);
    int len2 = pow((x2[hypo2] - x2[(hypo2 + 1) % k2]), 2) + pow((y2[hypo2] - y2[(hypo2 + 1) % k2]), 2);
    if(len1 == len2) return true;
    else return false;
}
bool judgeTrapWaist(int k1, int* x1, int* y1, int hypo1, int k2, int* x2, int* y2, int hypo2){    // 判断梯形的直角腰长是否相等
    int point1 = (hypo1 + 2) % k1;
    int point2 = (hypo2 + 2) % k2;
    int len1, len2;
    if(x1[point1] == x1[(point1 + 1) % k1]) len1 = abs(y1[point1] - y1[(point1 + 1) % k1]);
    else len1 = abs(x1[point1] - x1[(point1 + 1) % k1]);
    if(x2[point2] == x2[(point2 + 1) % k2]) len2 = abs(y2[point2] - y2[(point2 + 1) % k2]);
    else len2 = abs(x2[point2] - x2[(point2 + 1) % k2]);
    if(len1 == len2) return true;
    else return false;
}
int main(){
    int x1[11], y1[11], x2[11], y2[11];
    int n;
    cin >> n;
    for(int i = 0; i <= n - 1; i++){
        int k1, k2;
        cin >> k1;
        for(int j = 0; j <= k1 - 1; j++) cin >> x1[j] >> y1[j];
        cin >> k2;
        for(int j = 0; j <= k2 - 1; j++) cin >> x2[j] >> y2[j];
        if(!judgeVertex(k1, k2)){
            cout << "NO" << endl;
            continue;
        }
        int hypo1 = -1, hypo2 = -1;
        if(!judgeRAVert(k1, x1, y1, hypo1)){
            cout << "NO" << endl;
            continue;
        }
        if(!judgeRAVert(k2, x2, y2, hypo2)){
            cout << "NO" << endl;
            continue;
        }
        if(hypo1 == -1 && hypo2 == -1){
            int d11 = (x1[0] == x1[1] ? abs(y1[0] - y1[1]) : abs(x1[0] - x1[1]));
            int d12 = (x1[0] == x1[3] ? abs(y1[0] - y1[3]) : abs(x1[0] - x1[3]));
            int d21 = (x2[0] == x2[1] ? abs(y2[0] - y2[1]) : abs(x2[0] - x2[1]));
            int d22 = (x2[0] == x2[3] ? abs(y2[0] - y2[3]) : abs(x2[0] - x2[3]));
            if(d11 == d21 || d11 == d22 || d12 == d21 || d12 == d22){
                cout << "YES" << endl;
                continue;
            }
            else{
                cout << "NO" << endl;
                continue;
            }
        }
        else if(hypo1 == -1 || hypo2 == -1){
            cout << "NO" << endl;
            continue;
        }
        else{
            if(!judgeHypo(k1, x1, y1, hypo1, k2, x2, y2, hypo2)){
                cout << "NO" << endl;
                continue;
            }
            if(k1 == 4 && k2 == 4){    // 两个梯形
                if(!judgeTrapWaist(k1, x1, y1, hypo1, k2, x2, y2, hypo2)){
                    cout << "NO" << endl;
                    continue;
                }
            }
        }
        cout << "YES" << endl;
    }
    return 0;
}