阿里編程-城堡問題

題目:
將軍大勝歸來,奪取許多城堡(xi,yi)。國王許可,你站在任意的城堡上,選擇任意視角,看得見的城堡都是你的,包括你站的城堡,但頭不能動。而且你不能站在城堡構成的凸焦點上。將軍的視角剛好小於180度(無限接近180度),可以看得無限遠。請計算出將軍最多能得多少城堡。如果所有的城堡都在凸焦點上,那麼將軍一個城堡也得不到。
輸入:
第一行,整數m,表示接下來有m行。接下來的m行,每行都有2個數,表示一個城堡的座標。
輸出:
最多獲得的城堡個數。
輸入範例:
5
0 0
0 2
1 0
1 2
0.2 1.8
輸出範例:
4

#include <iostream>  
#include <vector>  
#include <numeric>  
#include <limits>
#include <bits/stdc++.h>  

using namespace std;  

// 請完成下面這個函數,實現題目要求的功能  
//當然,你也可以不按照這個模板來作答,完全按照自己的想法來 ^-^   
struct Point {      // 定義點類型  
    double x, y;  
    Point(double x1 = 0, double y1 = 0) :x(x1), y(y1) {}  
};  
Point castleHelp(Point p1, Point p2, Point p3) {    // 輸入3點,輸出位置和夾角  
    Point ret;  
    p2.x -= p1.x;  
    p2.y -= p1.y;  
    p3.x -= p1.x;  
    p3.y -= p1.y;  
    ret.x = p2.x * p3.y - p3.x * p2.y;  
    ret.y = acos((p2.x * p3.x + p2.y * p3.y) / sqrt((p2.x * p2.x + p2.y * p2.y) * (p3.x * p3.x + p3.y * p3.y)));  
    return ret;  
}  

int castle(vector<Point> points) {  
    int ret(0), vl(points.size());  
    if (vl < 4) return 0;  
    for (int k1(0); k1 < vl; ++k1)  
        for (int k2(0); k2 < vl; ++k2) {  
            if (k1 == k2) continue;  
            int n1(0), n2(0), n0(2);  
            double theta1(0), theta2(0);  
            for (int k3(0); k3 < vl; ++k3) {  
                if (k3 == k2 || k3 == k1) continue;  
                auto p(castleHelp(points[k1], points[k2], points[k3]));  
                if (p.y < 1e-9) ++n0;            // 在射線AB上  
                else {  
                    if (p.x > 0) ++n1, theta1 = theta1 < p.y ? p.y : theta1;      // 在直線一側  
                    else if(0 < p.x) ++n2, theta2 = theta2 < p.y ? p.y : theta2;  // 在直線另一側  
                }  
            }  
            if (acos(-1) < theta1 + theta2) {                    // 判斷是否則爲凸焦點  
                n1 = n1 < n2 ? n2 + n0 : n1 + n0;  
                ret = ret < n1 ? n1 : ret;  
            }  
        }  
    return ret;  
}  

int main() {  
    int points_size = 0;  
    cout << "請輸入點的個數:";  
    cin >> points_size;  
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  
    vector<Point> points;  
    Point points_item;  
    cout << "請依次輸入點的座標: x y" << endl;  
    for (int points_i =0; points_i < points_size; ++points_i) {  
        cin >> points_item.x >> points_item.y;  
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  
        points.push_back(points_item);  
    }  
    cout << castle(points) << endl;  

    return 0;  

}  
發佈了163 篇原創文章 · 獲贊 21 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章