Codeforces 101173 C - Convex Contour

思路:

如果所有的图形都是三角形,那么答案是2*n+1

否则轮廓肯定触到了最上面,要使轮廓线最短,那么轮廓肯定是中间一段平的

我们考虑先将轮廓线赋为2*n+2,然后删去左右两边多余的部分

如果最左边或最由边是正方形,那么不需要删

如果最左边或最由边是圆形,那么删取2 - pi/2

如果如果最左边或最由边是三角形,那么我们需要找到一段连续的三角形,然后考虑怎么删去

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

int main() {
    fio;
    int n;
    string s;
    cin >> n;
    cin >> s;
    bool f = true;
    for (int i = 0; i < n; i++) if(s[i] != ‘T‘) f = false;
    if(f) {
        cout << 2*n + 1 << endl;
    }
    else {
        double ans = 2*n + 2;
        if(s[0] == ‘T‘) {
            int x = 1;
            for (int i = 1; i < n; i++) {
                if(s[i] == ‘T‘) {
                    x++;
                }
                else if(s[i] == ‘C‘){
                    double tot = x + 0.5;
                    double t = sqrt((sqrt(3)/2 - 0.5)*(sqrt(3)/2 - 0.5) + x*x - 0.25);
                    tot -= t;
                    double a = atan((sqrt(3)/2 - 0.5) / x);
                    double b = atan(t*2);
                    double c = pi/2 -a - b;
                    tot -= c*0.5;
                    ans -= tot;
                    break;
                }
                else if(s[i] == ‘S‘) {
                    double tot = x;
                    double t = sqrt((1-sqrt(3)/2)*(1-sqrt(3)/2) + (x-0.5) * (x-0.5));
                    tot -= t;
                    ans -= tot;
                    break;
                }
            }
        }
        else if(s[0] == ‘C‘) {
            ans -= 2 - pi/2;
        }

        reverse(s.begin(), s.end());
        if(s[0] == ‘T‘) {
            int x = 1;
            for (int i = 1; i < n; i++) {
                if(s[i] == ‘T‘) {
                    x++;
                }
                else if(s[i] == ‘C‘){
                    double tot = x + 0.5;
                    double t = sqrt((sqrt(3)/2 - 0.5)*(sqrt(3)/2 - 0.5) + x*x - 0.25);
                    tot -= t;
                    double a = atan((sqrt(3)/2 - 0.5) / x);
                    double b = atan(t*2);
                    double c = pi/2 -a - b;
                    tot -= c*0.5;
                    ans -= tot;
                    break;
                }
                else if(s[i] == ‘S‘) {
                    double tot = x;
                    double t = sqrt((1-sqrt(3)/2)*(1-sqrt(3)/2) + (x-0.5) * (x-0.5));
                    tot -= t;
                    ans -= tot;
                    break;
                }
            }
        }
        else if(s[0] == ‘C‘) {
            ans -= 2 - pi/2;
        }
        cout << fixed << setprecision(9) << ans << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/widsom/p/9525149.html

时间: 2025-01-17 15:06:58

Codeforces 101173 C - Convex Contour的相关文章

[CERC2016]:凸轮廓线Convex Contour(模拟+数学)

题目描述 一些几何图形整齐地在一个网格图上从左往右排成一列.它们占据了连续的一段横行,每个位置恰好一个几何图形.每个图形是以下的三种之一:$1.$一个恰好充满单个格子的正方形.$2.$一个内切于单个格子的圆.$3.$一个底边与格子重合的等边三角形. 已知每个格子的边长都为$1$,请求出这些几何图形的凸包的周长. 输入格式 第一行包含一个正整数$n$,表示几何图形的个数.第二行包含$n$个字符,从左往右依次表示每个图形,$"S"$表示正方形,$"C"$表示圆形,$&q

【计算几何】【分类讨论】Gym - 101173C - Convex Contour

注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分类比较多. #include<cstdio> #include<cmath> using namespace std; const double PI=acos(-1.0); int n; char a[25]; struct Point{ double x,y; double len

OpenCV Tutorials &mdash;&mdash; Convex Hull

凸包 找到物体的轮廓之后,再找其凸包   void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true ) Parameters: points – Input 2D point set, stored in std::vector or Mat. hull – Output convex hull. It is either an integer vector

opencv笔记(二十四)——得到轮廓之后找到凸包convex hull

当我们得到一张轮廓之后,我们可以对其运用convexHull方法,寻找该轮廓的凸包. 一个轮廓可以有无数个包围它的外壳,而其中表面积最小的一个外壳,就是凸包. void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true ) points是一个contour. vector<Point>类型或者Mat类型 hull是输出,也是一个点集vector<Poin

Codeforces Round #198 (Div. 2)A,B题解

Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahub and his friend Floyd have started painting a wall. Iahub is painting the wall red and Floyd is painting it pink. You can consider the wall being mad

Codeforces 2A Winner (map运用)

Winner Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on CodeForces. Original ID: 2A 64-bit integer IO format: %I64d      Java class name: (Any) Prev Submit Status Statistics Discuss Next Type: None None Graph Theory      2-SAT 

轮廓的查找、表达、绘制、特性及匹配(How to Use Contour? Find, Component, Construct, Features &amp; Match)

http://www.cnblogs.com/xrwang/archive/2010/02/09/HowToUseContour.html 作者:王先荣 前言    轮廓是构成任何一个形状的边界或外形线.前面讲了如何根据色彩及色彩的分布(直方图对比和模板匹配)来进行匹配,现在我们来看看如何利用物体的轮廓.包括以下内容:轮廓的查找.表达方式.组织方式.绘制.特性.匹配. 查找轮廓    首先我们面对的问题是如何在图像中找到轮廓,OpenCv(EmguCv)为我们做了很多工作,我们的任务只是调用现成

Codeforces 932F - Escape Through Leaf

Problem Link: http://codeforces.com/contest/932/problem/F Problem Statement: F. Escape Through Leaf time limit per test: 3 seconds memory limit per test:256 megabytes input: standard input output: standard output You are given a tree with n nodes (nu

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多