POJ 2318
第一道计算几何。
二分一下用叉积来判。。看了DIS上说要INT64,就改INT64了。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int Max=5050; 7 8 struct e{ 9 int x1,x2; 10 }edge[Max]; 11 struct c{ 12 int x,y; 13 }cal[4]; 14 15 int n,m; 16 int X1,Y1,X2,Y2; 17 int ans[Max]; 18 int u,v; 19 20 void init(){ 21 for(int i=0;i<=n;i++){ 22 ans[i]=0; 23 } 24 } 25 26 bool in(){ 27 if(u>=X1&&u<=X2&&v>=Y2&&v<=Y1) 28 return true; 29 return false; 30 } 31 32 __int64 multi(int i){ 33 int j=i+1; 34 if(j==4) j=0; 35 return (__int64)(u-cal[i].x)*(__int64)(cal[j].y-cal[i].y)-(__int64)(v-cal[i].y)*(__int64)(cal[j].x-cal[i].x); 36 } 37 38 bool judge(int mid){ 39 __int64 pre,now; 40 cal[0].x=edge[mid].x1; cal[0].y=Y1; 41 cal[1].x=X2; cal[1].y=Y1; 42 cal[2].x=X2; cal[2].y=Y2; 43 cal[3].x=edge[mid].x2; cal[3].y=Y2; 44 for(int i=0;i<4;i++){ 45 now=multi(i); 46 if(i>0){ 47 if(pre*now<0) 48 return false; 49 } 50 pre=now; 51 } 52 return true; 53 } 54 55 void slove(){ 56 int low=0,high=n; 57 int anst; 58 while(low<=high){ 59 int mid=(low+high)/2; 60 if(judge(mid)){ 61 anst=mid; low=mid+1; 62 } 63 else high=mid-1; 64 } 65 ans[anst]++; 66 } 67 68 int main(){ 69 while(scanf("%d",&n)!=EOF){ 70 if(n==0) break; 71 scanf("%d%d%d%d%d",&m,&X1,&Y1,&X2,&Y2); 72 init(); 73 edge[0].x1=X1,edge[0].x2=X1; 74 for(int i=1;i<=n;i++){ 75 scanf("%d%d",&edge[i].x1,&edge[i].x2); 76 } 77 for(int i=0;i<m;i++){ 78 scanf("%d%d",&u,&v); 79 if(in()) 80 slove(); 81 } 82 for(int i=0;i<=n;i++) 83 printf("%d: %d\n",i,ans[i]); 84 printf("\n"); 85 } 86 return 0; 87 }