uva 109 SCUD Busters

題意:有很多國家,國家的邊界是包括房子和發電站的凸包,當發動戰爭是,會用飛毛腿導彈摧毀對方的發電站,則這個國家就會滅亡,給出每個國家的點的集合,包括房子和發電站,給出炮彈可以打中的點,計算出被摧毀的國家的總面積。

解題:計算出每個國家的凸包,如果沒打中了就計算面積,然後求和。即使被打中很多次的話,面積只能算一次的。

WA:cmp中,爲了防止超,就用了long long ,但是在計算時類型轉化出錯,等號右邊沒有強制轉化,但是其實用int就可以過,沒必要用大類型就不要用。

代碼:

//uva109 SCUD Busters
//AC By Warteac
//Runtime:0.015s
//2013-5-14
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include <iomanip>
#include<algorithm>
#include<cmath>
using namespace std;
typedef int PType;//定義點的類型
///////////////////////////////////////
struct point{
    PType x,y;
    point(PType a = 0, PType b = 0){x  = a; y = b;}
    void transfer(point p){x -= p.x, y -= p.y;}
    void restore(point p){x += p.x, y += p.y;}
    void print(){cout << "x = " << x << "y = " << y << endl;}  
};
int direction(point v1,point v2){
 	return (v1.x*v2.y-v1.y*v2.x);
 }
bool cmp(point p1, point p2){
    long long cosx1 = (long long)p1.x*p1.x*(p2.x*p2.x+p2.y*p2.y); //等號右邊一定要加long long,否則沒有效果
    long long cosx2 = (long long)p2.x*p2.x*(p1.x*p1.x+p1.y*p1.y);
    if(p1.x < 0) cosx1 *=(-1);
    if(p2.x < 0) cosx2 *=(-1);
    return cosx1 < cosx2;
}
/*
 經過簡化的cmp,避免了數據範圍過大的問題
 bool cmp(point p1,point p2){
   return (p1.x*p2.y < p1.y*p2.x);
}
*/
bool grham_scan(vector <point> p , vector <point> &parray){
//find first point p0 with minimum y-coordinate or minimun x-coordinate if y are the same
    PType x = p[0].x, y = p[0].y;
    int index = 0,i;
    for(i = 1; i < p.size(); i++){
        if(p[i].y > y) continue;
        if(p[i].y < y){
            y = p[i].y; x = p[i].x; index = i;
        }else if(p[i].x < x){
            y = p[i].y; x = p[i].x; index = i;
        }
    }
    point t = p[index];
    p[index] = p[0];
    p[0] = t;
//transfer points by p0
    for(int j = 0; j < p.size(); j++){
        p[j].transfer(t);
    }
//let (p1,p2……pm) sorted by polar angle
    sort(p.begin()+1,p.end(),cmp);
//delete those points with the same polar angle but the farthest ont from p0
    vector <point> ps;//saved in ps
    ps.clear();
    ps.push_back(p[0]);
    ps.push_back(p[1]);
    for(int i = 2; i < p.size(); i++){
        if(cmp(ps.back(),p[i])){
            ps.push_back(p[i]);   
        }else if(ps.back().x < p[i].x){
            ps.back() = p[i];
        }
    }
    if(ps.size() <= 2) return false;
//get the convex hull from ps
    parray.clear();
    parray.push_back(ps[0]);
    parray.push_back(ps[1]);
    ps.push_back(ps[0]);
    for(int i = 2; i < ps.size(); i++){
       point v1 (ps[i].x - parray.back().x, ps[i].y - parray.back().y);
       point v2 (parray.back().x - (parray.end()-2)->x, parray.back().y - (parray.end()-2)->y);
       int d = direction(v2,v1);
       if(d <= 0) {parray.push_back(ps[i]);}
       else if(d > 0){ 
       parray.pop_back();i--; 
       }
    }   
//restore the points' coordinate
    for(int j = 0; j < parray.size(); j++){
        parray[j].restore(t);
    }
    return true;
}
int areaOfPolygon(vector <point> &vecCH) {
    int nArea = 0;
    for (vector <point>::iterator i = vecCH.begin(); i != vecCH.end() - 1; ++i) {
        nArea += (i + 1)->x * i->y - i->x * (i + 1)->y;
    }
    return nArea;
}
bool inPolygon(point pt, vector <point> &vecCH) {
    for (vector <point>::iterator i = vecCH.begin(); i != vecCH.end() - 1; ++i) {
        int nX1 = pt.x - i->x, nY1 = pt.y - i->y;
        int nX2 = (i + 1)->x - i->x, nY2 = (i + 1)->y - i->y;
        if (nX1 * nY2 - nY1 * nX2 < 0) {
            return false;
        }
    }
    return true;
}
//////////////////////////////////////////////////////
int main(){
    int sites;
    PType x,y;
    vector <point> v;
    point t,mi;
    vector < vector <point> >  p;//convex hull
    int aflag[105] = {0};
    int area = 0;
    //input kingdom
    while(cin >> sites && sites != -1){
        v.clear();
        vector <point> temp;//one convex hull
        while(sites--){
	        cin >> t.x >> t.y;
	        v.push_back(t);
        }
        //computing convex hull
	    if(grham_scan(v,temp) == true){
        p.push_back(temp);//all convex hull
	    }
     }
     //input missile landings
     while(cin >> mi.x >> mi.y){
         for(int j = 0; j < p.size(); j++){
	         if((inPolygon(mi,p[j]) == true) && aflag[j] != 1){
	         aflag[j] = 1;
	         area += areaOfPolygon(p[j]);
	         break;
	         }
	     }
     }
     cout << setiosflags(ios::fixed) << setprecision(2);
     cout << (double)area/2.0 << endl;
 return 0;
}


 

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