下午和隊友一起做了下杭州賽區的比賽題,結果被虐了,只過了三題,兩個隊友沒一會兒就開始打醬油。。。。實在受不了。
這道題裸的計算幾何,求出多邊形的重心,求重凸包,然後直接判斷重心到凸包各點的投影是否線上段上,注意這裡不用求出投影直接用點積即可,隊友看錯題WA了一次,我看了發現90的時候是不穩的。。。。到此整題就理論AC了,只要代碼穩,可以輕鬆拿下。
My Code:
#include <cstdio><br />#include <cstring><br />#include <cstdlib><br />#include <cmath><br />#include <vector><br />#include <algorithm></p><p>using namespace std;</p><p>const int MAX=50100;<br />const double oo=1e10;<br />const double eps=1e-8;</p><p>struct Point{<br /> double x,y;<br /> double angle,dis;</p><p> Point(){</p><p> }<br /> Point(double x,double y):x(x),y(y){</p><p> }<br />};</p><p>struct Line{<br /> Point p1,p2;</p><p> Line(){</p><p> }<br /> Line(Point p1,Point p2):p1(p1),p2(p2){</p><p> }<br />};</p><p>typedef vector<Point> Polygon;<br />typedef vector<Point> Points;</p><p>bool ZERO(double x){<br /> return fabs(x)<eps;<br />}</p><p>bool ZERO(Point p){<br /> return ZERO(p.x)&&ZERO(p.y);<br />}</p><p>bool EQ(double x,double y){<br /> return fabs(x-y)<eps;<br />}</p><p>bool NEQ(double x,double y){<br /> return fabs(x-y)>=eps;<br />}</p><p>bool LT(double x,double y){<br /> return NEQ(x,y)&&x<y;<br />}</p><p>bool GT(double x,double y){<br /> return NEQ(x,y)&&x>y;<br />}</p><p>bool LEQ(double x,double y){<br /> return EQ(x,y)||x<y;<br />}</p><p>bool GEQ(double x,double y){<br /> return EQ(x,y)||x>y;<br />}</p><p>double sqr(double x){<br /> return x*x;<br />}</p><p>bool operator==(const Point& p1,const Point& p2){<br /> return EQ(p1.x,p2.x)&&EQ(p1.y,p2.y);<br />}</p><p>bool operator!=(const Point& p1,const Point& p2){<br /> return NEQ(p1.x,p2.x)||NEQ(p1.y,p2.y);<br />}</p><p>bool operator<(const Point& p1,const Point& p2){<br /> if(NEQ(p1.x,p2.x)){<br /> return p1.x<p2.x;<br /> }else{<br /> return p1.y<p2.y;<br /> }<br />}</p><p>Point operator+(const Point& p1,const Point& p2){<br /> return Point(p1.x+p2.x,p1.y+p2.y);<br />}</p><p>Point operator-(const Point& p1,const Point& p2){<br /> return Point(p1.x-p2.x,p1.y-p2.y);<br />}</p><p>double operator*(const Point& p1,const Point& p2){<br /> return p1.x*p2.y-p1.y*p2.x;<br />}</p><p>double operator&(const Point& p1,const Point& p2){<br /> return p1.x*p2.x+p1.y*p2.y;<br />}</p><p>double Norm(const Point& p){<br /> return sqrt(sqr(p.x)+sqr(p.y));<br />}</p><p>bool comp(const Point& left,const Point& right){<br /> if(EQ(left.angle,right.angle)){<br /> return left.dis<right.dis;<br /> }else{<br /> return left.angle<right.angle;<br /> }<br />}</p><p>void Scan(Points& points,Polygon& result){<br /> int i,k,n;<br /> Point p;<br /> n=points.size();<br /> result.clear();</p><p> if(n<3){<br /> result=points;<br /> return;<br /> }</p><p> k=0;<br /> for(i=1;i<n;i++){<br /> if(EQ(points[i].y,points[k].y)){<br /> if(points[i].x<=points[k].x){<br /> k=i;<br /> }<br /> }else if(points[i].y<points[k].y){<br /> k=i;<br /> }<br /> }<br /> swap(points[0],points[k]);</p><p> for(i=1;i<n;i++){<br /> points[i].angle=atan2(points[i].y-points[0].y,points[i].x-points[0].x);<br /> points[i].dis=Norm(points[i]-points[0]);<br /> }<br /> sort(points.begin()+1,points.end(),comp);<br /> result.push_back(points[0]);<br /> for(i=1;i<n;i++){<br /> if((i+1<n)&&EQ(points[i].angle,points[i+1].angle)){<br /> continue;<br /> }<br /> if(result.size()>=3){<br /> p=result[result.size()-2];<br /> while(GEQ((points[i]-p)*(result.back()-p),0)){<br /> result.pop_back();<br /> p=result[result.size()-2];<br /> }<br /> }<br /> result.push_back(points[i]);<br /> }<br />}</p><p>Point center(const Polygon& poly){<br /> Point p,p0,p1,p2,p3;<br /> double m,m0;</p><p> p1=poly[0];<br /> p2=poly[1];<br /> p.x=p.y=m=0;</p><p> for(int i=2;i<(int)poly.size();i++){<br /> p3=poly[i];<br /> p0.x=(p1.x+p2.x+p3.x)/3.0;<br /> p0.y=(p1.y+p2.y+p3.y)/3.0;<br /> m0=p1.x*p2.y+p2.x*p3.y+p3.x*p1.y-p1.y*p2.x-p2.y*p3.x-p3.y*p1.x;<br /> if(ZERO(m+m0)){<br /> m0+=eps;<br /> }<br /> p.x=(m*p.x+m0*p0.x)/(m+m0);<br /> p.y=(m*p.y+m0*p0.y)/(m+m0);<br /> m+=m0;<br /> p2=p3;<br /> }</p><p> return p;<br />}</p><p>bool isconter(const Points pts){<br /> double res=0.0;<br /> int n=pts.size();<br /> for(int i=0;i<n;i++){<br /> res+=(pts[i]*pts[(i+1)%n]);<br /> }<br /> return res>0;<br />}</p><p>bool check(const Point& p,const Line& l){<br /> return LT((l.p1-p)&(l.p2-l.p1),0)&<((l.p2-p)&(l.p1-l.p2),0);<br />}</p><p>Points pts,poly;</p><p>int main(){<br /> int t;<br /> int n,ret;<br /> Point p;</p><p> scanf("%d",&t);<br /> while(t--){<br /> scanf("%d",&n);<br /> ret=0;<br /> pts.clear();<br /> for(int i=0;i<n;i++){<br /> scanf("%lf%lf",&p.x,&p.y);<br /> pts.push_back(p);<br /> }<br /> if(!isconter(pts)){<br /> reverse(pts.begin(),pts.end());<br /> }<br /> p=center(pts);<br /> Scan(pts,poly);<br /> n=poly.size();<br /> poly.push_back(poly[0]);<br /> for(int i=0;i<n;i++){<br /> if(check(p,Line(poly[i],poly[i+1]))){<br /> ret++;<br /> }<br /> }</p><p> printf("%d/n",ret);<br /> }</p><p> return 0;<br />}<br />