题意:
给定n个位于第一和第二象限的点,每一个点都有一个符号表示
给出一个序列,问从x轴的哪些区间从做往右看刚好符合这个序列
题解:
输入后进行极坐标排序,以负无穷为源点,按角的大小降序排列,若有相同角的就按照近的在前
再计算区间的分割点
然后枚举区间,看是否符合题意
这里不需要在枚举区间的时候都进行极坐标排序,只需要经过一个区间分割点的时候将两个字母换一个位置即可
#include<vector>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
vector<pair<double,double> >ans;
#define MAXN 110
#define inf 0x3f3f3f3f
const double eps=1e-8;
char str[MAXN];
int now[MAXN*MAXN];
struct Point
{
char ch[5];
double x,y;
Point(){}
Point(double _X, double _Y){
x = _X; y = _Y;
}
};
Point P[MAXN];
struct Line
{
double x;
int t1,t2;
Line(){}
Line(double _x,int _t1,int _t2){
x=_x,t1=_t1,t2=_t2;
}
};
Line line[MAXN*MAXN];
double Cross(Point p1,Point p2,Point p3){
return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);
}
double Dis(Point A, Point B){
return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));
}
Point operator - (Point A,Point B){
return Point(A.x-B.x, A.y-B.y);
}
Point operator + (Point A, Point B){
return Point(A.x+B.x, A.y+B.y);
}
Point operator * (Point A, double p){
return Point(A.x*p, A.y*p);
}
bool operator == (Point A, Point B){
return (A.x-B.x) == 0 && (A.y-B.y) == 0;
}
int sgn(double x)
{
if(fabs(x)<eps)
return 0;
if(x<0)
return -1;
return 1;
}
bool cmp(Point a, Point b)///按极角降序排序,若角度相等距离小的在前面
{