[Gym - 100517K] Kingdom Division 2 二分

Posted cjbiantai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Gym - 100517K] Kingdom Division 2 二分相关的知识,希望对你有一定的参考价值。

大致题意:

  给出一个凸包,以及凸包内的两个点p1,p2,求有多少条经过凸包顶点的直线能够将凸包分割为两部分,且给出的两点分别属于不同的部分

  

  枚举凸包的顶点,二分求出p1,p2线段左边的最大坐标L以及右边的最小坐标R,则答案为R-L-1的累加和除以2

  注意文件输入,输出

   

技术分享图片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<set>
  7 #include<map>
  8 #include<stack>
  9 #include<time.h>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<list>
 13 using namespace std;
 14 #define MAXN 100100
 15 #define eps 1e-9
 16 #define For(i,a,b) for(int i=a;i<=b;i++) 
 17 #define Fore(i,a,b) for(int i=a;i>=b;i--) 
 18 #define lson l,mid,rt<<1
 19 #define rson mid+1,r,rt<<1|1
 20 #define mkp make_pair
 21 #define pb push_back
 22 #define cr clear()
 23 #define sz size()
 24 #define met(a,b) memset(a,b,sizeof(a))
 25 #define iossy ios::sync_with_stdio(false)
 26 #define fre freopen
 27 #define pi acos(-1.0)
 28 #define inf 1e6+7
 29 #define Vector Point
 30 const int Mod=1e9+7;
 31 typedef unsigned long long ull;
 32 typedef long long ll;
 33 int dcmp(double x){
 34     if(fabs(x)<=eps) return 0;
 35     return x<0?-1:1;
 36 }
 37 struct Point{
 38     double x,y;
 39     int id;
 40     Point(double x=0,double y=0):x(x),y(y) {}
 41     bool operator < (const Point &a)const{
 42         if(x==a.x) return y<a.y;
 43         return x<a.x;
 44     }
 45     Point operator - (const Point &a)const{
 46         return Point(x-a.x,y-a.y);
 47     }
 48     Point operator + (const Point &a)const{
 49         return Point(x+a.x,y+a.y);
 50     }
 51     Point operator * (const double &a)const{
 52         return Point(x*a,y*a);
 53     }
 54     Point operator / (const double &a)const{
 55         return Point(x/a,y/a);
 56     }
 57     void read(){
 58         scanf("%lf%lf",&x,&y);
 59     }
 60     void out(){
 61         cout<<"debug: "<<x<<" "<<y<<endl;
 62     }
 63     bool operator == (const Point &a)const{
 64         return dcmp(x-a.x)==0 && dcmp(y-a.y)==0;
 65     }
 66 };
 67 double Dot(Vector a,Vector b) {
 68     return a.x*b.x+a.y*b.y;
 69 }
 70 double dis(Vector a) {
 71     return sqrt(Dot(a,a));
 72 }
 73 double Cross(Point a,Point b){
 74     return a.x*b.y-a.y*b.x;
 75 }
 76 int n;
 77 Point p[200005];
 78 int ls,rs;
 79 int chk1(Point p1,Point p2,int pos){
 80     int l=pos+1,r=pos+n-1;
 81     while(l<r){
 82         int mid=l+r>>1;
 83         if(dcmp(Cross(p[mid]-p[pos],p1-p[pos]))<=0 && dcmp(Cross(p[mid]-p[pos],p2-p[pos])<=0)) r=mid;
 84         else l=mid+1;
 85     }
 86     return l;
 87 }
 88 int chk2(Point p1,Point p2,int pos){
 89     int l=pos+1,r=pos-1+n;
 90     while(l<r){
 91         int mid=l+r+1>>1;
 92         if(dcmp(Cross(p[mid]-p[pos],p1-p[pos]))>=0 && dcmp(Cross(p[mid]-p[pos],p2-p[pos]))>=0) l=mid;
 93         else r=mid-1;
 94     }
 95     return l;
 96 }
 97 Point p1,p2;
 98 void solve(){
 99     For(i,1,n) p[i].read();
100     p1.read();p2.read();
101     ll ans=0;
102     For(i,1,n) p[i+n]=p[i];
103     For(i,1,n){
104         ls=chk1(p1,p2,i);
105         rs=chk2(p1,p2,i);
106         if(ls!=rs)ans+=abs(ls-rs)-1;
107     }
108     cout<<ans/2<<endl;
109 }
110 int main(){
111 //    fre("in.txt","r",stdin);
112     freopen("kingdom.in","r",stdin);
113     freopen("kingdom.out","w",stdout);
114     int t=0;
115      while(~scanf("%d",&n) &&n)    solve();
116     return 0;
117 }
View Code

 

以上是关于[Gym - 100517K] Kingdom Division 2 二分的主要内容,如果未能解决你的问题,请参考以下文章

Kingdom and its Cities - CF613D

Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 并查集求奇偶元环

Gym 101102D---Rectangles(单调栈)

Gym - 100989D-Cafeteria (B)

Gym 100989 D

gym 101657 D