弧度制区间的表示
对于一段弧度区间(小于360度),我们可以用两个数表示,分别是起点的弧度和终点的弧度,例如 。
为了统一化,先确定起点弧度 ,使得终点弧度 。注意, ,此时加上后 时,同时减去 即可保证 。
这样做有什么好处呢?假设两个弧度区间进行交操作,有以下几种情况:
- 有交集,显然在同一参考系。
- 无交集,可能是在同一参考系内确实无交集;或者不在一个参考系,让 较大的区间 减去 ,再进行比较。
代码:
#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
*/