弧度制区间的表示(D - Dazzling stars)

弧度制区间的表示

对于一段弧度区间(小于360度),我们可以用两个数表示,分别是起点的弧度和终点的弧度,例如 [ π , 0.5 π ] [-\pi,0.5\pi]

为了统一化,先确定起点弧度 P P ,使得终点弧度 Q = P + Q=P+\angle 。注意, P [ 0 , 2 π ] P\in[0,2\pi] ,此时加上后 Q > 2 π Q>2\pi 时,同时减去 2 π 2\pi 即可保证 P , Q [ 2 π , 2 π ] P,Q\in[-2\pi,2\pi]

这样做有什么好处呢?假设两个弧度区间进行交操作,有以下几种情况:

  • 有交集,显然在同一参考系。
  • 无交集,可能是在同一参考系内确实无交集;或者不在一个参考系,让 Q Q 较大的区间 P , Q P,Q 减去 2 π 2\pi ,再进行比较。

代码:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const double pi=acos(-1);
const double eps=1e-6;

int dcmp(double x){return fabs(x)<eps?0:(x>0?1:-1); }

struct arc{
    double l,r;
    arc(){}
    arc(double l,double r){
        if(r>2*pi){
            r-=2*pi,l-=2*pi;
        }
        this->l=l,this->r=r;
    }
    pair<bool,arc> operator *(const arc &A)const{
        if(dcmp(min(r,A.r)-max(l,A.l))>=0){
            return {1,arc(max(l,A.l),min(r,A.r))};
        }
        arc x,y;
        if(r>A.r){
            x=arc(l,r),y=arc(A.l+2*pi,A.r+2*pi);
        }
        else{
            x=arc(l+2*pi,r+2*pi),y=arc(A.l,A.r);
        }
        if(dcmp(min(x.r,y.r)-max(x.l,y.l))>=0){
            return {1,arc(max(x.l,y.l),min(x.r,y.r))};
        }
        return {0,A};
    }
};

int main(){
    arc x(1-2*pi,2-2*pi),y(0,1.5);
    auto I=x*y;
    printf("%.2f %.2f\n",I.second.l,I.second.r);
}
// 1.00 1.50

题目

http://codeforces.com/gym/102428/problem/D

题意: 有一些带权二维点,现在要求旋转坐标轴,使得权大的点在权小的点上方或同一高度。

解析:

假设a权小于b权:
在这里插入图片描述
显然,只要y轴正方向落在a连向b的直线所对应的180度扇形区域内即可。

我们用弧度制来表示这个区域,处理交集即可。

#include<bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=a;i<=b;i++)
const double pi=acos(-1);
const int maxn=1e3+9;
const double eps=1e-6;
int n;
double x[maxn],y[maxn];
int b[maxn];
int dcmp(double x){
    return fabs(x)<eps?0:(x>0?1:-1);
}

int main(){
    scanf("%d",&n);
    rep(i,1,n){
        scanf("%lf%lf%d",x+i,y+i,b+i);
    }
    double L=0,R=2*pi;
    rep(i,1,n){
        rep(j,i+1,n){
            if(b[i]!=b[j]){
                double dx=x[j]-x[i],dy=y[j]-y[i];
                if(dcmp(dx)==0&&dcmp(dy)==0)continue;
                if(b[i]>b[j]){
                    dx*=-1;
                    dy*=-1;
                }
                double bx=dy,by=-dx,ex=-bx,ey=-by;
                double b_ang,e_ang;
                if(dcmp(bx)>0&&dcmp(by)>=0){
                    b_ang=atan(by/bx);
                }
                else if(dcmp(bx)<=0&&dcmp(by)>0){
                    b_ang=pi/2+atan(-bx/by);
                }
                else if(dcmp(bx)<0&&dcmp(by)<=0){
                    b_ang=pi+atan(by/bx);
                }
                else{
                    b_ang=pi*3.0/2+atan(-bx/by);
                }
                e_ang=b_ang+pi;
                if(e_ang>2*pi){
                    e_ang-=2*pi;
                    b_ang-=2*pi;
                }
                if(dcmp(min(R,e_ang)-max(L,b_ang))>=0){
                    R=min(R,e_ang);
                    L=max(L,b_ang);
                }
                else {
                    if(R>e_ang)R-=2*pi,L-=2*pi;
                    else e_ang-=2*pi,b_ang-=2*pi;
                    if(dcmp(min(R,e_ang)-max(L,b_ang))>=0){
                        R=min(R,e_ang);
                        L=max(L,b_ang);
                    }
                    else{
                        return 0*printf("N\n");
                    }
                }
            }
        }
    }
    puts("Y");
}
/*
4
-1 2 5
0 0 2
3 4 1
4 2 4
*/
发布了723 篇原创文章 · 获赞 314 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/103151099