【HDU 1115】
【题目大意】求多边形的重心
【解题分析】直接推公式,cx=∑x*面积 / 总面积 ,cy对称
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const double eps = 1e-9; 6 const int MAXN = 1e6 +5; 7 int sgn(double x) 8 { 9 if (x < -eps) return -1; 10 if (x > eps) return 1; 11 return 0; 12 } 13 struct V 14 { 15 double x, y; 16 double ang; 17 double angle() 18 {//求取极 19 return atan2(y,x); 20 } 21 V(double X = 0, double Y = 0) 22 { 23 //初始化 24 x = X, y = Y; 25 ang = atan2(y, x); 26 } 27 bool operator <(const V &b) 28 { 29 return ang<b.ang; 30 } 31 bool operator ==(const V &b) 32 { 33 return sgn(x - b.x) && sgn(y - b.y); 34 } 35 36 }; 37 typedef V P; 38 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 39 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 40 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 41 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 42 //叉积 43 double cross(V a, V b) 44 { 45 return a.x*b.y - a.y*b.x; 46 } 47 double cross(V a, V b, V c) 48 { 49 return cross(a - c, b - c); 50 } 51 //点积 52 double dot(V a, V b) 53 { 54 return a.x*b.x + a.y*b.y; 55 } 56 double area(P *p, int n) 57 { 58 double res = 0; 59 p[n + 1] = p[1]; 60 for (int i = 1; i <= n; i++) 61 res += cross(p[i], p[i + 1]); 62 return res / 2; 63 } 64 P p[MAXN]; 65 int main() 66 { 67 int T; 68 scanf("%d", &T); 69 while (T--) 70 { 71 int N, n = 0; 72 scanf("%d", &N); 73 for (int i = 1; i <= N; i++) 74 { 75 ++n; 76 scanf("%lf %lf", &p[n].x, &p[n].y); 77 } 78 double low = 0; 79 double ansx = 0, ansy = 0; 80 P a[5]; 81 a[1] = p[1], a[2] = p[2]; 82 for (int i = 3; i <= n; i++) 83 { 84 a[3] = p[i]; 85 double s = area(a, 3); 86 low += s; 87 double tx = (a[1].x + a[2].x + a[3].x) , 88 ty = (a[1].y + a[2].y + a[3].y) ; 89 ansx += tx * s; 90 ansy += ty * s; 91 a[2] = a[3]; 92 } 93 ansx = ansx /low/3; 94 ansy = ansy /low/3; 95 printf("%.2f %.2f\n", ansx,ansy); 96 } 97 return 0; 98 }
【UVALive 3263】That Nice Euler Circuit
【题目大意】给定几个点,给出顺序为他们被一笔画的顺序,最后结尾在最开始的点形成一个闭合的图形,问这个一笔画把这个平面分成了几个部分
【题目分析】
因为有交点,有边线,这个问题可以转化成,求一个多边形有多少个面
开始这里想不通为什么要这么求,用空间思想想一下,按照每条边并在一起这样分的话是不是就能够形成一个多面体
而有欧拉定理,E为点数,V为边数,F为面数,有公式:F + V - E = 2
所以我们最后所求的面数即为:F = ( E + 2 - V )
然后我们计算有多少条边和点,就能够得到答案
对于点的情况:需要排除掉几根线交于一点的情况
对于边的情况:线上没多出一点就会被分割出来一条边
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN = 90005; 7 const double eps = 1e-9; 8 int sgn(double x) 9 { 10 if (x < -eps) return -1; 11 if (x > eps) return 1; 12 return 0; 13 } 14 struct V 15 { 16 double x, y; 17 double ang; 18 double angle() 19 {//求取极角 20 return atan2(y, x); 21 } 22 V(double X = 0, double Y = 0) 23 { 24 //初始化 25 x = X, y = Y; 26 ang = atan2(y, x); 27 } 28 bool operator ==(const V &b) 29 { 30 return sgn(x - b.x)==0 && sgn(y - b.y)==0; 31 } 32 bool operator<(V a) 33 { 34 return x < a.x || (x == a.x && y < a.y); 35 } 36 }; 37 typedef V P; 38 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 39 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 40 double operator *(V a, V b) { return a.x*b.x + a.y*b.y; } 41 double operator ^(V a, V b) { return a.x*b.y - b.x*a.y; } 42 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 43 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 44 //叉积 45 double cross(P a, P b ,P c) 46 { 47 return (a - c) ^ (b - c); 48 } 49 struct L 50 { 51 P s, t; 52 double ang; 53 L(P X = V(), P Y = V()) 54 { 55 s = X, t = Y, ang = (Y - X).angle(); 56 } 57 }; 58 P p[MAXN],v[MAXN]; 59 L l[MAXN]; 60 //求两线段是否相交 61 bool L_is_inter(L a, L b) 62 { 63 return 64 max(a.s.x, a.t.x) >= min(b.s.x, b.t.x) && 65 max(b.s.x, b.t.x) >= min(a.s.x, a.t.x) && 66 max(a.s.y, a.t.y) >= min(b.s.y, b.t.y) && 67 max(b.s.y, b.t.y) >= min(a.s.y, a.t.y) && 68 sgn((b.s - a.s) ^ (a.t - a.s))*sgn((b.t - a.s) ^ (a.t - a.s)) < 0 && 69 sgn((a.s - b.s) ^ (b.t - a.s))*sgn((a.t - b.s) ^ (b.t - b.s)) < 0; 70 } 71 P intersection(L a, L b) 72 { 73 return a.s + (a.t - a.s)*(((b.t - b.s)^(a.s - b.s)) / ((a.t - a.s)^( b.t - b.s))); 74 } 75 bool P_is_onL(P a, P b,P c) 76 { 77 78 return sgn((b-a)^(c-a)) == 0 && sgn((b-a)*(c-a)) < 0; 79 } 80 int main() 81 { 82 83 int n; int cas = 0; 84 while (scanf("%d", &n)) 85 { 86 if (n == 0) break; 87 int m = 0, c = 0; 88 for (int i = 1; i <= n; i++) 89 scanf("%lf %lf", &p[i].x, &p[i].y), v[i] = p[i]; 90 n--; 91 for (int i = 1; i <= n; i++) 92 { 93 l[++m] = L(p[i], p[i + 1]); 94 } 95 c = n; 96 for (int i = 1; i <= n; i++) 97 { 98 for (int j = i+1; j <= n; j++) 99 { 100 if (L_is_inter(l[i], l[j])) 101 { 102 v[++c] = intersection(l[i], l[j]); 103 } 104 } 105 } 106 int e = m; 107 sort(v + 1, v + 1 + c); 108 c = unique(v + 1, v + 1 + c) - (v); 109 c--; 110 for (int i = 1; i <= c; i++) 111 { 112 for (int j = 1; j <= n; j++) 113 { 114 if (P_is_onL(v[i],p[j], p[j+1])) 115 e++; 116 } 117 } 118 printf("Case %d: There are %d pieces.\n",++cas,e + 2 - c); 119 } 120 return 0; 121 }