2014-08-29 解題區/解題區 - UVa UVa 12322 - Handgun Shooting Sport contents 1. Problem2. Sample Input3. Sample Output4. Solution Problem給第一、二象限的的線段,請問至少要從原點射幾發子彈才能將其全部射到。 Sample Input1234567891011121314151617181920212223242526272829303132333435363710-309 98 -258 204-303 83 -251 98-218 111 -287 31-145 204 -23 257-129 272 59 272-8 159 74 130150 146 68 17459 196 128 24298 256 241 235197 61 173 923-100 10 -100 50-50 100 50 100100 10 100 505-100 100 100 100-80 120 80 120-60 140 60 140-40 160 40 160-20 180 20 1802-50 50 0 50-10 70 50 702-50 50 0 500 70 50 702-50 50 0 5010 70 50 705-4 10 0 25 10 0 1-2 1 -3 44 10 2 100 9 -2 90 Sample Output12345674311123 Solution將線段轉換成極角區間,之後帶入掃描線算法。 123456789101112131415161718192021222324252627282930313233343536373839#include <stdio.h>#include <vector>#include <queue>#include <algorithm>#include <string.h>#include <math.h>using namespace std;int main() { int n, x1, x2, y1, y2; while (scanf("%d", &n) == 1 && n) { vector< pair<double, double> > interval; for (int i = 0; i < n; i++) { scanf("%d %d %d %d", &x1, &y1, &x2, &y2); double l = atan2(y1, x1), r = atan2(y2, x2); if (l > r) swap(l, r); interval.push_back(make_pair(l, r));// printf("[%lf %lf]\n", l, r); } sort(interval.begin(), interval.end()); int ret = 0;#define eps 0 for (int i = 0, j; i < interval.size(); ) { ret++; double coverR = interval[i].second;// printf("try [%lf %lf]\n", interval[i].first, interval[i].second); for (j = i; j < interval.size() && interval[j].first <= coverR + eps; j++) coverR = min(coverR, interval[j].second); i = j; } printf("%d\n", ret); } return 0;}/* */ Newer UVa 12379 - Central Post Office Older UVa 12307 - Smallest Enclosing Rectangle