计算几何
1.https://codeforces.com/problemset/problem/40/A 放到第一象限再判断
int n,k;
struct Point {
int x,y;
int id;
Point() {}
Point(double x,double y):x(x),y(y) {}
Point operator - (Point B) {
return Point(x-B.x,y-B.y);
}
bool operator == (Point B) {
return x == B.x && y == B.y;
}
};
int Distance(Point A,Point B) {
// return hypot(A.x-B.x,A.y-B.y);
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
void work(){
double x,y;
scanf("%lf%lf",&x,&y);
if(abs(x) < eps || abs(y) < eps){
cout << "black" << endl;
return ;
}
if(y < 0){
x = -x;
y = -y;
}
int tt=0;
if(x < 0){
x = -x;
tt=1;
}
int q=0;
for(double i=0;;i+=1){
if(fabs(i*i-x*x-y*y) < eps || fabs((i+1)*(i+1)-x*x-y*y) < eps){
cout << "black" << endl;
return ;
}
if(x*x+y*y > i*i && x*x+y*y < (i+1)*(i+1)){
int t = (int)i;
if(t&1)q=1;//白
else q=0;
break;
}
}
if(tt){
q = 1-q;
}
if(q)cout << "white" << endl;
else cout << "black" << endl;
}
2.https://codeforces.com/problemset/problem/614/C
一个多边形绕一个点旋转一周,问覆盖的面积
先坐标转化成绕原点,可以发现,找到距离圆心的最远点和最近点,形成的圆环就是答案,然后最远的点一定是顶点,最近的可能是线段,要求点/线段到原点的距离.
const int N = 1e5 + 50;
const int INF = 0x7fffffff;
const double eps = 1e-9;
const double PI = acos(-1);
int sgn(double x) {
if(fabs(x) < eps)return 0;
else return x<0?-1:1;
}
struct Point {
double x,y;
Point() {}
Point(double x,double y):x(x),y(y) {}
Point operator - (Point B) {
return Point(x-B.x,y-B.y);
}
bool operator == (Point B) {
return x == B.x && y == B.y;
}
};
struct Line {
Point p1,p2;//线上的两个点
Line() {}
Line(Point p1,Point p2):p1(p1),p2(p2) {}
};
double Distance(Point A,Point B) {
return hypot(A.x-B.x,A.y-B.y);
// return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
double Cross(Point a,Point b) {
return a.x*b.y-a.y*b.x;
}
int n;
Point o,p[N];
typedef Point Vector;
typedef Line Segment;
double Dot(Vector A,Vector B) {
return A.x*B.x + A.y*B.y;
}
//点到直线的距离
double Dis_point_line(Point p, Line v) {
return fabs(Cross(p-v.p1,v.p2-v.p1))/Distance(v.p1,v.p2);
}
//点到线段的距离
double Dis_point_seg(Point p, Segment v) {
if(sgn(Dot(p- v.p1,v.p2-v.p1))<0 || sgn(Dot(p- v.p2,v.p1-v.p2))<0)
return min(Distance(p,v.p1),Distance(p,v.p2));
return Dis_point_line(p,v); //点的投影在线段上
}
void work() {
scanf("%d%lf%lf",&n,&o.x,&o.y);
double maxn=0,minx = INF;
Point z=Point(0,0);
for(int i=0; i<n; i++) {
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i] = p[i] - o;
maxn=max(maxn,Distance(p[i],z));
minx=min(minx,Distance(p[i],z));
}
p[n] = p[0];
for(int i=1; i<=n; i++) {
minx = min(minx,Dis_point_seg(z,Line(p[i],p[i-1])));
// printf("%d ----- %lf
",i,Dis_point_seg(z,Line(p[i],p[i-1])));
}
// cout << minx << " " << maxn << endl;
double ans = PI * (maxn*maxn - minx*minx);
printf("%.8f
",ans);
}
3.https://codeforces.com/problemset/problem/667/A 水题
double d,h,v,e;
void work(){
scanf("%lf%lf%lf%lf",&d,&h,&v,&e);
v /= PI*(d/2.0)*(d/2.0);
double hh = v;
if(h + e*100000 > hh * 100000)printf("NO
");
else {
double t = h / (hh-e);
printf("YES
");
printf("%.6f
",t);
}
}
4.https://codeforces.com/problemset/problem/672/C
由于中间的路都是点到原点的距离,那么分三种情况:
1)只有一个人在走,那就只有一段Dis(第一次遇到的点,A或B)
2)两个人都在走,有两段不完整的. 用la,lb,lt表示,只有A动,只有b动,a和b都动的情况,具体看注释
struct Point {
double x,y;
Point() {}
Point(double x,double y):x(x),y(y) {}
Point operator - (Point B) {
return Point(x-B.x,y-B.y);
}
bool operator == (Point B) {
return x == B.x && y == B.y;
}
};
double Distance(Point A,Point B) {
return hypot(A.x-B.x,A.y-B.y);
// return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
Point A,B,o;
int n;
Point p[N];
void work() {
scanf("%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&o.x,&o.y);
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%lf%lf",&p[i].x,&p[i].y);
}
double la=Distance(p[0],A)+Distance(p[0],o); //当前只有A动
double lb=Distance(p[0],B)+Distance(p[0],o); //当前只有B动
double lt=min(la,lb); //两个都动
double sum=Distance(p[0],o)*2; //记录走过前i个点的长度
for(int i=1;i<n;i++){
double nl = Distance(p[i],o);
//AB都走 = Min{前i-1个只有a动,当前B动 || 前i-1个只有b动,当前A动 || 之前两个都动,当前不动}
lt = min(min(la + Distance(p[i],B)+nl,lb+Distance(p[i],A)+nl),lt+2*nl);
//a走 = Min{之前用过机会了,当前走完整 || 之前的完整+当前不完整}
la = min(la+2*nl,sum+Distance(p[i],A)+nl);
lb = min(lb+2*nl,sum+Distance(p[i],B)+nl);
sum += 2*nl;
}
printf("%.8f
",min(min(la,lb),lt));
}