poj 2398 Toy Storage (计算几何,判断点和线段关系)

http://poj.org/problem?id=2398

题意大概是说将一个盒子用n个board分成n+1 部分

然后往里面放toy,给定盒子,board,和toy的坐标

问所有的toy放完后,有多少部分中有t个toy;

简单计算几何

需要判断的是点和直线的关系.

判断 某一点在直线左右侧

左右方向是相对前进方向的,只要指定了前进方向就可以知道左右(比如指定前进方向是从直线的起点到终点).判断点在直线的左侧还是右侧是计算几何里面的一个最基本算法.使用矢量来判断.
定义:平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量:

**
S(P1,P2,P3)=|y1 y2 y3|= (x1-x3)(y2-y3)-(y1-y3)(x2-x3)

当P1P2P3逆时针时S为正的,当P1P2P3顺时针时S为负的。

令矢量的起点为A,终点为B,判断的点为C,
如果S(A,B,C)为正数,则C在矢量AB的左侧;
如果S(A,B,C)为负数,则C在矢量AB的右侧;
如果S(A,B,C)为0,则C在直线AB上。**

  1
  2
  3 
  4
  5    
  6    /*************************************************************************
  7    	> File Name: code/poj/2398.cpp
  8    	> Author: 111qqz
  9    	> Email: rkz2013@126.com 
 10    	> Created Time: 2015年11月08日 星期日 10时04分32秒
 11     ************************************************************************/
 12    #include<iostream>
 13    #include<iomanip>
 14    #include<cstdio>
 15    #include<algorithm>
 16    #include<cmath>
 17    #include<cstring>
 18    #include<string>
 19    #include<map>
 20    #include<set>
 21    #include<queue>
 22    #include<vector>
 23    #include<stack>
 24    using namespace std;
 25    #define REP(i, n) for (int i=0;i<int(n);++i)  
 26    typedef long long LL;
 27    typedef unsigned long long ULL;
 28    const int N=2E3+5;
 29    struct node
 30    {
 31        int x,y;
 32    };
 33    struct node rec,rec2;
 34    struct node par[N],par2[N];
 35    struct node toy[N];
 36    int ans[N],cnt[N];
 37    int n,m;
 38    bool judge(node p1,node p2,node p3) //判断点是否在直线的[右侧!!]
 39    {
 40        int s = (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
 41        if (s>0) return false;
 42        if (s<0) return true;
 43    }
 44    bool cmp(node a,node b)
 45    {
 46        if (a.x<b.x) return true;
 47        if (a.x==b.x&&a.y<b.y) return true;
 48        return false;
 49    }
 50    int main()
 51    {
 52       // freopen("in.txt","r",stdin);
 53        while (scanf("%d",&n)!=EOF&&n)
 54        {
 55    	  memset(ans,0,sizeof(ans));
 56    	  memset(par,0,sizeof(par));
 57    	  memset(par2,0,sizeof(par2));
 58    	  memset(toy,0,sizeof(toy));
 59    	  cin>>m>>rec.x>>rec.y>>rec2.x>>rec2.y;
 60    	  for ( int i = 1 ;  i <= n ; i++)
 61    	  {
 62    		cin>>par[i].x>>par2[i].x;
 63    		par[i].y=rec.y;
 64    		par2[i].y=rec2.y;
 65    	  }
 66    	  for ( int i = 1 ; i <= n-1 ; i++)
 67    	  {
 68    		for ( int j = i+1 ; j <= n ; j++)
 69    		{
 70    		    if (par[i].x>par[j].x)
 71    		    {
 72    			  swap(par[i].x,par[j].x);
 73    		    //  swap(par[i].y,par[j].y);
 74    			  swap(par2[i].x,par2[j].x);
 75    		    //   swap(par2[i].y,par2[j].y);
 76    		    }
 77    		}
 78    	  }
 79    //	  for ( int i = 1 ;  i <= n ; i++)
 80    //		cout<<par[i].x<<endl;
 81    	  for ( int i = 1 ;  i <= m ; i++ )
 82    	   {
 83    		cin>>toy[i].x>>toy[i].y;
 84    	   }
 85    	  int p;
 86    	  sort(toy+1,toy+m+1,cmp);  //如果第i个娃娃在第k个分划中,那么排序后第i+1个娃娃至少在第k个分划中....(某大神说过,顺手就能写的优化顺手	
 87    //	  for ( int i = 1 ; i <= m ; i++)  cout<<"x[i]:"<<toy[i].x<<" y[i]:"<<toy[i].y<<endl;
 88    	  for ( int i = 1 ; i  <= m ;  i++) 
 89    	  {
 90    		p = n + 1;  //如果在所有board的右侧,那么一定是在最后一个分划中(n个板子形成n+1个分划)
 91    		bool ok=false;
 92    		for ( int j = 1 ; j  <= n ; j++)
 93    		{
 94    		    ok=judge(par2[j],par[j],toy[i]);
 95    		    if (!ok)
 96    		    {
 97    		//	  cout<<"i:"<<i<<" j:"<<j<<" "<<par2[j].x<<" "<<par2[j].y<<" "<<par[j].x<<" "<<par[j].y<<endl;
 98    			  p = j;
 99    			  break;
100    			//    cout<< "hhhhhh"<<"I:"<<i<<" j:"<<j<<endl;
101    		    }
102    		}
103    		ans[p]++;
104    	  }
105    	  cout<<"Box"<<endl;
106    	  memset(cnt,0,sizeof(cnt));
107    	  for ( int i = 1 ; i <= n+1 ; i++)
108    	  {
109    		if (ans[i]==0) continue;
110    		cnt[ans[i]]++;
111    //		printf("%d: %d\n",i-1,ans[i]);
112    	  } 
113    //	  puts("");
114    	  for ( int i = 1 ; i <= m ;  i++)
115    	  {
116    		if (cnt[i]==0) continue;
117    	  	printf("%d: %d\n",i,cnt[i]);
118    	  }
119        }
120        return 0;
121    }
122    
123