HDU 4380 - Farmer Greedy

来源:互联网 发布:品牌管理课程 知乎 编辑:程序博客网 时间:2024/05/21 07:03

 

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4380

 

2012年第9场多校,1001 。

 

补上。

 

其实这个做法当时有想到,只是找不出 O(n^3)  范围内 求V的求法。 所以当时只好放弃~ 。。。

 

赛后才知道,有其实多校第6场,电科的1004跟这题基本上一样。。。  木有来得及去看,尴尬了。。。

 

不过电科牛给的 V的求法,其思想有点类似于单调队列,只不过队列只有一个元素。。。

 

以前没想到这种思想还可以用在几何上(做的几何题目太少,木有遇到过),各种新颖。。。

 

好吧,写写过了~~   2Y

 

写完调试过一阵,原因是while写成if 。

 

CE过一次,原因是 atan2 的参数是double,而我直接放整型进去(编译器没报错)。。。

 

PS:  后来做了 电科原题,才发现原来我代码是错的,只不过这题数据太弱了,擦,交了两次不同的错代码上去都能AC。。。

        还是电科出题严谨啊,数据、标程、描述等质量都严格把关,佩服~~~

 

 

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespace std;const double pi=3.1415926;const double eps=0e-6;struct Point{int x,y;}pq[1110];struct Angle{double agl;int id_;Angle(){};Angle(Point a,Point b,int i){agl=atan2((double)b.x-a.x,(double)b.y-a.y);id_=i; } }r[3000];int pn,qn,pqn,rn;void input(){int i;pqn=pn+qn;for(i=0;i<pqn;++i)scanf("%d%d",&pq[i].x,&pq[i].y);}int cmp(Angle a,Angle b){return a.agl<b.agl; }int s[103][103];int v[103][103],v_id[103][103];void init_(){int i,j,k,cnt,mark;for(i=0;i<pn;++i){rn=0;for(j=0;j<pqn;j++)if(i!=j) r[rn++]=Angle(pq[i],pq[j],j);sort(r,r+rn,cmp);for(j=0;j<rn;j++){r[rn+j]=r[j];r[rn+j].agl+=2*pi;}cnt=0;mark=0;for(j=k=0;j<rn;j++){while(r[k].agl-r[j].agl<pi)if(r[k++].id_>=pn) cnt++;if(r[j].id_< pn){s[i][r[j].id_]=cnt;v[i][r[j].id_]=mark;v_id[i][r[j].id_]=j;}else{mark++,cnt--;}}}}int xmult(Point a,Point b,Point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); }int get_v(int a,int b,int c){if(v_id[a][b]>v_id[a][c]) return v[a][b]-v[a][c];return qn+v[a][b]-v[a][c];}int get_sum(int a,int b,int c){int sum=0;if(xmult(pq[a],pq[b],pq[c])<0) swap(b,c);sum+=s[a][b]+s[b][c]+s[c][a];sum+=get_v(a,b,c)+get_v(b,c,a)+get_v(c,a,b);return sum;}int deal(){int i,j,k,res=0;for(i=0;i<pn;i++) for(j=i+1;j<pn;j++)for(k=j+1;k<pn;k++)res+=get_sum(i,j,k)&1;return res;}int main(){int t=1;while(~scanf("%d%d",&pn,&qn)){input();init_();printf("Case %d: %d\n",t++,deal());} return 0;}