C - Convex Contour(轮廓线)

Problem

  • 求轮廓线,图形由三角,圆,正方形拼成,三角为等边三角形。

Solution

  • 大体框架还是找到最左边和最右边的方或圆(可以将轮廓线撑起来),然后算出两边三角包括三角与其他图形相连部分的轮廓线长度,然后算中间部分的轮廓线长度。
  • 注意三角和圆轮廓线是与圆相切的。

Code

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double pai=3.14159265358979;
char s[25];
double ans;
int fir,last;
int main()
{
    int n;
    cin>>n;
    getchar();
    for(int i=1;i<=n;i++)
        s[i]=getchar();
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='C'||s[i]=='S')
        {
            fir=i;
            break;
        }
    }
    for(int i=n;i>=1;i--)
    {
        if(s[i]=='C'||s[i]=='S')
        {
            last=i;
            break;
        }
    }
    if(n==1)//一个时
    {
        if(s[1]=='T')
            ans=3;
        if(s[1]=='C')
            ans=pai;
        if(s[1]=='S')
            ans=4;
        printf("%.9lf",ans);
        return 0;
    }
    if(fir)//有方或圆
    {
        if(last-fir>1)//算中间
        ans+=(last-fir-1)*2;
        if(fir>=2)//算左边三角
        {
            ans+=2;
            for(int i=2;i<fir;i++)
                ans+=1;
            double dis=0.5+(fir-2),dis0=sqrt((fir-1)*(fir-1)+(sqrt(3)/2-0.5)*(sqrt(3)/2-0.5)),d0=sqrt(dis0*dis0-0.25);
            double d1=pai/2-asin(d0/dis0)-asin((sqrt(3)/2-0.5)/dis0);
            if(s[fir]=='C')//
                ans+=d0+d1/2;
            else
                ans+=sqrt(dis*dis+((1-sqrt(3)/2)*(1-sqrt(3)/2)));

        }

        if(last<n)//算右边三角
        {
            ans+=2;
            for(int i=n-1;i>last;i--)
                ans+=1;
            double dis=0.5+(n-last-1),dis0=sqrt((n-last)*(n-last)+(sqrt(3)/2-0.5)*(sqrt(3)/2-0.5)),d0=sqrt(dis0*dis0-0.25);
            double d1=pai/2-asin(d0/dis0)-asin((sqrt(3)/2-0.5)/dis0);
            if(s[last]=='C')
                ans+=d0+d1/2;
            else
                ans+=sqrt(dis*dis+((1-sqrt(3)/2)*(1-sqrt(3)/2)));
        }
        if(fir==last)//只有一个
        {
            if(fir==1||fir==n)//在边上
            {
                if(s[fir]=='S')
                    ans+=3;
                else
                    ans+=(pai/2+0.5);
            }
            else{//不在边上
                if(s[fir]=='S')
                    ans+=2;
                else
                    ans+=1;
            }
        }
        else{//两个都有
            if(fir==1)//第一个在边上
                ans+=(s[fir]=='S'?3:pai/2+1);
            else
                ans+=(s[fir]=='S'?2:1.5);
            if(last==n)
               ans+=(s[last]=='S'?3:pai/2+1);
            else
                ans+=(s[last]=='S'?2:1.5);
        }
    }
    else
        ans=5+(n-2)*2;
    printf("%.11lf",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈希表扁豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值