列表

详情


NC203374. 多边形与圆

描述

一个半径为r的空心圆,内部有一个n个点的凸多边形,这个多边形在圆壳的内部滚动。多边形顶点按照逆时针顺序给出,保证每一个顶点都有机会接触圆壳。

起初,1号点,2号点一定在圆上,初始以1号点为轴心、然后依次以2, 3, ..., n号点为轴心“滚动”。具体地讲,在以i号点为轴心“滚动”时,多边形将保持i号点不动,并以该点为中心开始顺时针旋转,直到i+1号点接触圆为止,然后更换轴心,继续“滚动”。

求多边形从初始开始滚动、直到1号点再次到达圆上成为轴心为止,1号点在整个滚动过程中所经过的路程是多少。

输入描述

第一行输入两个正整数 
接下来 n 行,每行两个浮点数 代表 i 号点的初始坐标。

输出描述

输出一行一个浮点数,代表答案。

示例1

输入:

3 5
0 0
1 0
0 3

输出:

8.05082557797666886756

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 5ms, 内存消耗: 496K, 提交时间: 2020-03-21 12:46:51

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a),_5=(b);i<_5;++i)
struct P{
    double x,y;
} p[110];
#define dis(a,b) hypot(p[a].x-p[b].x, p[a].y-p[b].y)
int main(){
    int n,r;cin>>n>>r;
    rep(i,1,n+1) cin>>p[i].x>>p[i].y;
    double ans=0;
    rep(i,2,n +1) {
        double arc = dis(1,i);
        double b=dis(i-1,i),c=dis(i,i%n+1),a=dis(i-1,i%n+1);
        double rad = acos(b/2/r)+acos(c/2/r)-acos((b*b+c*c-a*a)/2/b/c);
        ans+=rad*arc;
    }
    cout.precision(17);
    cout<<ans<<endl;
}

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2020-03-20 20:20:20

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n;double r,ans;
struct poi{double x,y;}p[N];
double dis(poi a,poi b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
int main(){
	scanf("%d%lf",&n,&r);
	for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
	for(int i=2;i<=n;i++){
		double l=dis(p[1],p[i]),a=dis(p[i-1],p[i%n+1]),b=dis(p[i-1],p[i]),c=dis(p[i],p[i%n+1]);
		double ci=acos(b/2/r)+acos(c/2/r)-acos((b*b+c*c-a*a)/(2*b*c));
		ans+=l*ci;
	}
	printf("%.9lf",ans);
	return 0;
}

上一题