题意:

一个n边型,给出n个顶点,在给你一个图形内部的一点x,然后n边型沿着边开始滚动,每个边只滚动一次,问x的运动距离

题解:

很好想,每次滚动都是弧形
距离 = 弧度 * 半径
距离求和就行
弧度可以由角度得到
角度可以由余弦定理得到
图片说明
图片说明
但是我计算几何做的不多。。。求其弧度来及其费力

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
struct Point{
    double x,y;
    Point(){}
    Point(double xx,double yy):x(xx),y(yy){}

}p[100],V[100];
double Dot(Point A ,Point B)//向量 
{
    return A.x*B.x+A.y*B.y;
}
double Length(Point A)
{
    return sqrt(Dot(A,A));
}
double Angle(Point A,Point B)//计算角度 
{
    return acos(Dot(A,B)/(Length(A)*Length(B)));
}
double Dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double dis[100];
//p是记录点 v是记录向量 
double Qx,Qy;
double PI=acos(-1);//就是π 
int main()
{
    int t;
    cin>>t;
    for(int ii=1;ii<=t;ii++)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>p[i].x>>p[i].y;
        }
        cin>>Qx>>Qy;
        int tot=0;
        for(int i=1;i<n;i++)
        {
            dis[++tot]=Dis(p[i].x,p[i].y,Qx,Qy);
            V[i].x=p[i].x-p[i+1].x;
            V[i].y=p[i].y-p[i+1].y;
        }
        dis[n]=Dis(p[n].x,p[n].y,Qx,Qy);
        V[n].x=p[n].x-p[1].x;
        V[n].y=p[n].y-p[1].y;
        double ans=0;
        for(int i=2;i<=n;i++)
        {
            ans+=Angle(V[i],V[i-1])*dis[i];
        }
        ans+=Angle(V[1],V[n])*dis[1];
        printf("Case #%d: %0.3lf\n",ii,ans);
    }
    return 0;
}