zoukankan      html  css  js  c++  java
  • 计算几何(二)

    计算几何

    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));
    	
    }
    
    
  • 相关阅读:
    ORA-04091错误原因与解决方法
    Vue中过滤器及自定义插件
    解决 React 中的 input 输入框在中文输入法下的 bug
    总结18个webpack插件
    使用Vue Composition API写出清晰、可扩展的表单
    实现微前端需要了解的 Vue Genesis 渲染器
    React 监听页面滚动,界面动态显示
    漫谈受控与非受控组件
    vue的完整版和运行时版的区别
    vue中利用provide和inject实现页面刷新(无白屏)重载组件
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/15027979.html
Copyright © 2011-2022 走看看