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
",i,ans[i]);
84         printf("
");
85     }
86     return 0;
87 }
View Code
原文地址:https://www.cnblogs.com/jie-dcai/p/3864320.html