开始学习计算几何(本蒟蒻发现,做了一天题,就一个叉积有点卵用2333,(还是做题太少了(太弱了)))
这个题,可以发现,对于答案所在区间是有单调性的(在答案区间的左边的叉积和在右边的叉积正负是不同的),所以可以二分了
1 #include<cstdio> 2 #include<cstring> 3 #define N 1000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 11 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 12 return x*f; 13 } 14 int n,m,ans[5005]; 15 struct point{int x,y;}; 16 struct segment{point a,b;}s[5005]; 17 point sub(point a, point b){ 18 point t; t.x=a.x-b.x, t.y=a.y-b.y; return t; 19 } 20 int cross(point a, point b){ 21 return a.x*b.y-b.x*a.y; 22 } 23 int turn(point p1, point p2, point p3){ 24 return cross(sub(p2,p1),sub(p3,p1)); 25 } 26 void search(point x) 27 { 28 int l=1,r=n,tmp=0; 29 while (l<=r) 30 { 31 int mid=l+r>>1; 32 if (turn(s[mid].a,s[mid].b,x)>=0) tmp=mid,l=mid+1; 33 else r=mid-1; 34 } 35 ans[tmp]++; 36 } 37 int main() 38 { 39 while (scanf("%d",&n) && n) 40 { 41 memset(ans,0,sizeof(ans)); 42 int x1,x2,y1,y2,t1,t2; 43 scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); 44 for (int i=1; i<=n; i++) 45 { 46 scanf("%d%d",&t1,&t2); 47 s[i].a.x=t1; s[i].a.y=y1; 48 s[i].b.x=t2; s[i].b.y=y2; 49 } 50 for (int i=1; i<=m; i++) 51 { 52 point t; 53 scanf("%d%d",&t.x,&t.y); 54 search(t); 55 } 56 for (int i=0; i<=n; i++) 57 printf("%d: %d\n",i,ans[i]); 58 puts(""); 59 } 60 return 0; 61 }
感觉这道题不用神奇的叉积也是可以做的,,,,
原文:http://www.cnblogs.com/ccd2333/p/6480795.html