HDU–3685[Rotational Painting] 求重心+凸包

來源:互聯網
上載者:User

穩定的定義:
多邊形玻璃板的重心向水平面作垂線時,垂足落在支撐邊所在的線段上(不包括線段端點)。

對多邊形支撐邊的枚舉:
由於有可能出現凹多邊形,因此可供選擇的“支撐邊”包括該多邊形的凸包的所有邊。

 

思路:
先求重心,然後再求凸包,枚舉凸包的每條邊判斷是否可以是支撐邊。(注意重心到某條支撐邊的交點在端點算不合法)

CODE:

/*求重心+凸包*//*AC代碼:187ms*/#include <iostream>#include <cstdio>#include <algorithm>#define MAXN 50005using namespace std;/*==================================================*\ | Graham 求凸包 O(N * logN) | CALL: nr = graham(pnt, int n, res); res[]為凸包點集; \*==================================================*/ struct point {double x,y;};struct point pnt[MAXN],res[MAXN],center; int N,M;bool mult(point sp,point ep,point op){ return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y); } bool operator<(const point &l,const point &r){ return l.y<r.y||(l.y==r.y&&l.x<r.x); }int graham(point pnt[],int n,point res[])//注意都是從0開始存{ int i,len,k=0,top=1; sort(pnt,pnt+n); if (n == 0) return 0; res[0]=pnt[0]; if (n == 1) return 1; res[1]=pnt[1]; if (n == 2) return 2; res[2]=pnt[2]; for(i=2;i<n;i++) { while(top&&mult(pnt[i],res[top],res[top-1]))top--; res[++top]=pnt[i]; } len=top;res[++top]=pnt[n-2]; for(i=n-3;i>=0;i--) { while(top!=len&&mult(pnt[i],res[top],res[top-1]))top--; res[++top]=pnt[i]; } return top;       // 返回凸包中點的個數 }//----------------------------------------------------------////----------------------------------------------------------// // 求多邊形重心 // INIT: pnt[]已按順時針(或逆時針)排好序; // CALL: res = bcenter(pnt, n); //----------------------------------------------------------// point bcenter(point pnt[], int n){ point p, s; double tp, area = 0, tpx = 0, tpy = 0; p.x = pnt[0].x; p.y = pnt[0].y; for (int i = 1; i <= n; ++i) {   // point: 0 ~ n-1 s.x = pnt[(i == n) ? 0 : i].x; s.y = pnt[(i == n) ? 0 : i].y; tp = (p.x * s.y - s.x * p.y); area += tp / 2; tpx += (p.x + s.x) * tp; tpy += (p.y + s.y) * tp; p.x = s.x; p.y = s.y; } s.x = tpx / (6 * area); s.y = tpy / (6 * area); return s; } void Init(){int i;scanf("%d",&N);for(i=0;i<N;i++)scanf("%lf%lf",&pnt[i].x,&pnt[i].y); center=bcenter(pnt,N);M=graham(pnt,N,res);}double mul(point p1,point p2)//點積{return p1.x*p2.x+p1.y*p2.y;}bool Judge(point p1,point p2)//判斷兩個夾角是否都是銳角{point a,b;double x1,x2,y1,y2,xo,yo;x1=p1.x;y1=p1.y;x2=p2.x;y2=p2.y;xo=center.x;yo=center.y;a.x=(x2-x1);a.y=(y2-y1);b.x=(xo-x1);b.y=(yo-y1);if(mul(a,b)<=0) return false;a.x=(x1-x2);a.y=(y1-y2);b.x=(xo-x2);b.y=(yo-y2);if(mul(a,b)<=0) return false;return true;} void Solve(){int i,ans=0;for(i=0;i<M-1;i++)ans+=Judge(res[i],res[i+1]);ans+=Judge(res[M-1],res[0]);//printf("&%.3lf %.3lf\n",center.x,center.y);printf("%d\n",ans);}int main(){int T;scanf("%d",&T);while(T--){Init();Solve();}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.