Fencing the Cows [USACO]
2013-04-19 12:23
267 查看
这道题目是很标准的凸包问题,看了第五章开头的说明,照着写就好。 判断向量夹角用交叉积,右手螺旋,注意交叉积不满足交换率,所以要注意前后顺序。
/* ID: zhangyc1 LANG: C++ TASK: fc */ #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; struct SPoint { double x, y, theta; }; SPoint arrPoint[10000], centerPoint; int arrChosen[10000]; int N; int compare(const void* argv1, const void* argv2) { if (((SPoint*)argv1)->theta < ((SPoint*)argv2)->theta) return -1; else if (((SPoint*)argv1)->theta > ((SPoint*)argv2)->theta) return 1; else return 0; } inline bool IsAngleConvex(SPoint& P1, SPoint& Pc, SPoint& P3) { // Convex : (P3 - PC) X (P1 - PC) > 0 return (P3.x - Pc.x) * (P1.y - Pc.y) - (P3.y - Pc.y) * (P1.x - Pc.x) > 0; } void GiftWrapping() { // 选前两个点 arrChosen[0] = 0, arrChosen[1] = 1; int nIdx = 2, nCur = 1, nSt = 0; // 选中间节点 while (nIdx < N) { while (nCur > 0 && !IsAngleConvex(arrPoint[arrChosen[nCur - 1]], arrPoint[arrChosen[nCur]], arrPoint[nIdx])) nCur--; arrChosen[++nCur] = nIdx; nIdx++; } // 选最后一个节点 while (1) { // ncur-1, ncur, nst 不为凹 if (nCur - nSt > 2 && !IsAngleConvex(arrPoint[arrChosen[nCur - 1]], arrPoint[arrChosen[nCur]], arrPoint[arrChosen[nSt]])) { nCur--; continue; } // ncur, nst, nst+1 不为凹 if (nCur - nSt > 2 && !IsAngleConvex(arrPoint[arrChosen[nCur]], arrPoint[arrChosen[nSt]], arrPoint[arrChosen[nSt + 1]])) nSt++; else break; } // 计算周长 double dbLen = sqrt((arrPoint[arrChosen[nSt]].x - arrPoint[arrChosen[nCur]].x) * (arrPoint[arrChosen[nSt]].x - arrPoint[arrChosen[nCur]].x) + (arrPoint[arrChosen[nSt]].y - arrPoint[arrChosen[nCur]].y) * (arrPoint[arrChosen[nSt]].y - arrPoint[arrChosen[nCur]].y)); for (int i = nSt + 1; i <= nCur; i++) { dbLen += sqrt((arrPoint[arrChosen[i]].x - arrPoint[arrChosen[i - 1]].x) * (arrPoint[arrChosen[i]].x - arrPoint[arrChosen[i - 1]].x) + (arrPoint[arrChosen[i]].y - arrPoint[arrChosen[i - 1]].y) * (arrPoint[arrChosen[i]].y - arrPoint[arrChosen[i - 1]].y)); } printf("%.2lf\n", dbLen); } void prepairData() { scanf("%d", &N); centerPoint.x = centerPoint.y = 0.0; for (int i = 0; i < N; i++) { scanf("%lf%lf", &arrPoint[i].x, &arrPoint[i].y); centerPoint.x += arrPoint[i].x; centerPoint.y += arrPoint[i].y; } centerPoint.x /= N; centerPoint.y /= N; } void process() { for (int i = 0; i < N; i++) { arrPoint[i].theta = atan2(arrPoint[i].y - centerPoint.y, arrPoint[i].x - centerPoint.x); } qsort(arrPoint, N, sizeof(SPoint), compare); GiftWrapping(); } int main(){ freopen("fc.in","r",stdin); freopen("fc.out","w",stdout); prepairData(); process(); return 0; }
相关文章推荐
- USACO Fencing the Cows 解题报告
- 计算几何 usaco Fencing the Cows 圈奶牛
- [USACO5.1]圈奶牛Fencing the Cows(凸包模板)
- P2742 [USACO5.1]圈奶牛Fencing the Cows
- USACO Section 5.1 Fencing the Cows - 凸包模板题~~
- USACO5.1.1 Fencing the Cows(fc)
- 凸包——Luogu2742 [USACO5.1]圈奶牛Fencing the Cows
- P2742 [USACO5.1]圈奶牛Fencing the Cows
- usaco fencing the cows
- [luogu2742]:[USACO5.1]圈奶牛Fencing the Cows
- Fencing the Cows_usaco 5.1_凸包
- [USACO5.1]Fencing the Cows
- usaco 5.1.1 Fencing the Cows
- USACO 5.1 fencing the cows——计算几何/凸包模板
- C++&Pascal——【USACO 5.1.1】——Fencing the Cows
- 【USACO 5.1.1】Fencing the Cows
- USACO Section 5.1 Fencing the Cows(凸包)
- 太感动了!第一次自己打出了USACO的题~ [USACO5.1]圈奶牛Fencing the Cows
- USACO 5.1 Fencing the Cows
- USACO 5.1 Fencing the Cows(凸包)