UVA 109 SCUD Busters【凸包模拟题】
2013-05-07 02:27
405 查看
题目大意:世界由几个互不重叠领土但彼此敌对的国家组成,每个国家有一个发电站,负责给本国发电。
1,给出每个国家的建筑数(包括发电站和房子数),每个国家用最少的围墙将本国保护起来(凸包);
2,现在有不定数量的飞毛腿导弹开始袭击这些国家,给出导弹落地点,落在某国区域内,某国直接玩完,以该国面积为大小的区域不能发电;
3,求出最后所有不能发电区域的总面积;
解题策略:
算法思路:求出每个国家的凸包并计算面积——导弹挨个判定在不在凸包内——若在,则累加当前凸包面积
注意:若某国家之前被导弹袭击过,之后再被袭击的话,面积只能算一次;
PS:这题临睡前抱着试试的态度做了下,按照自己的理解,设计好数据结构和算法,没想到1A,时间已是2:00,爽爆了!!!有木有!!!
明天一早还要编译原理,目测明天事情也比较多,苦逼了,速度睡觉!!!
1,给出每个国家的建筑数(包括发电站和房子数),每个国家用最少的围墙将本国保护起来(凸包);
2,现在有不定数量的飞毛腿导弹开始袭击这些国家,给出导弹落地点,落在某国区域内,某国直接玩完,以该国面积为大小的区域不能发电;
3,求出最后所有不能发电区域的总面积;
解题策略:
算法思路:求出每个国家的凸包并计算面积——导弹挨个判定在不在凸包内——若在,则累加当前凸包面积
注意:若某国家之前被导弹袭击过,之后再被袭击的话,面积只能算一次;
PS:这题临睡前抱着试试的态度做了下,按照自己的理解,设计好数据结构和算法,没想到1A,时间已是2:00,爽爆了!!!有木有!!!
明天一早还要编译原理,目测明天事情也比较多,苦逼了,速度睡觉!!!
/* UVA 109 SCUD Busters AC by J_Dark ON 2013/5/7 2:20 根本没想到会1A啊!!!!!爽爆了!!!!!! Time 0.015s */ #include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; const int maxn = 110; ///////////////////////////////////////// struct point{ double x, y; point(double a, double b){ x = a; y = b; } }; struct Kingdom{ double area; bool use; int top; vector<int> CH; Kingdom(){ area = 0; top = 1; CH.clear(); CH.resize(maxn); CH[0] = 0; CH[1] = 1; use = false; //未被导弹袭击 } }; vector<point> P, M; //临时点集 导弹 vector< vector<point> > kdNode; //记录国家点的信息 vector<Kingdom> KD; //国家 int nodeNum; double ansArea=0; //不能发电区域面积 ///////////////////////////////////////// void Input(){ P.clear(); //M.clear(); //CH.clear(); double xx, yy; if(nodeNum != -1){ for(int i=0; i<nodeNum; i++){ cin >> xx >> yy; P.push_back(point(xx, yy)); } kdNode.push_back(P); } else{ while(cin >> xx >> yy) M.push_back(point(xx, yy)); } } //求凸包 bool cmp(point a, point b){ if(a.y == b.y) return a.x < b.x; return a.y < b.y; } //判断向量p2-pp是否在向量p1-p2右侧 bool turnRight(point p1, point p2, point pp){ const double eps = 1e-20; if((p2.x - p1.x)*(pp.y - p2.y) - (pp.x - p2.x)*(p2.y - p1.y) <= eps) return true; return false; } //计算叉积 double multi(point p0, point p1, point p2){ return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y); } void Compute(){ //计算每个国家的凸包 //cout << kdNode.size() << endl << endl; for(int k=0; k<kdNode.size(); k++){ sort(kdNode[k].begin(), kdNode[k].end(), cmp); KD.push_back(Kingdom()); //从起点0到到排序最后点作凸包右链 过程1 for(int i=2; i<kdNode[k].size(); i++){ while( KD[k].top && turnRight(kdNode[k][KD[k].CH[KD[k].top-1]], kdNode[k][KD[k].CH[KD[k].top]], kdNode[k][i]) ) { KD[k].top--; } KD[k].CH[++KD[k].top] = i; } int len = KD[k].top; //从排序最高点到到起点0fab反向作凸包右链 过程2 KD[k].CH[++KD[k].top] = kdNode[k].size()-2; for(int i=kdNode[k].size()-3; i>=0; i--){ //KD[k].top!=len, 不考虑已在过程1生成凸包上的点 while( KD[k].top!=len && turnRight(kdNode[k][KD[k].CH[KD[k].top-1]], kdNode[k][KD[k].CH[KD[k].top]], kdNode[k][i]) ) { KD[k].top--; } KD[k].CH[++KD[k].top] = i; } //计算每个国家凸包面积 for(int i=1; i<KD[k].top-1; i++){ KD[k].area += multi(kdNode[k][KD[k].CH[0]], kdNode[k][KD[k].CH[i]], kdNode[k][KD[k].CH[i+1]]); } //printf("KD[%d].area = %lf\n", k, KD[k].area); //判断导弹是否袭击当前国家 for(int m=0; m<M.size(); m++){ if(KD[k].use) break; //该国家之前已被导弹摧毁 for(int i=0; i<KD[k].top-1; i++){ if(!turnRight(kdNode[k][KD[k].CH[i]], kdNode[k][KD[k].CH[(i+1)%KD[k].top]], M[m]))//若点M[m]在凸包边左侧 KD[k].use = true; //该国家可能会被袭击 else{ KD[k].use = false; //点M[m]不在凸包内部,导弹无法袭击 break; } } if(KD[k].use){ //该国家已被当前导弹摧毁 ansArea += KD[k].area; break; } } } printf("%.2lf\n", ansArea/2); //由于按方向分解凸包时,叉积计算为三角形有效面积2倍,故总和应除以2 } ///////////////////////////////////////// int main(){ while(cin >> nodeNum) { Input(); if(nodeNum == -1) Compute(); } return 0; }
相关文章推荐
- UVa 109 SCUD Busters (凸包面积&判断点是否在凸包内部)
- UVa 109 - SCUD Busters(凸包)
- UVA 109 || SCUD Busters(凸包面积计算
- UVa 109 - SCUD Busters(凸包计算)
- UVa 109 - SCUD Busters
- uva 109 SCUD Busters-AC-Upgraded version
- poj 1264 || UVA 109 SCUD Busters
- UVa Problem 109 - SCUD Busters
- uva 109 SCUD Busters
- uva 109 SCUD Busters
- POJ 1264 SCUD Busters (凸包面积+判断点是否在凸包内)
- uva109求凸包面积,判断点是不是在凸包内
- poj 1264 hdu 1616 SCUD Busters 凸包+面积计算
- UVA 10173 最小矩形覆盖(凸包+旋转卡壳)
- UVA 11168 Airport(凸包+直线方程)
- UVA 11168 Airport(凸包+直线方程)
- UVA 11168 Airport 凸包+直线的一般式
- UVA 10256 The Great Divide(凸包划分)
- UVA - 10652 Board Wrapping (二维凸包)
- UVa 10256 凸包简单应用