列表

详情


NC201952. 圆

描述

一个半径为 的圆周上有 个点,现在想要移动它们使得它们位于圆周的 等分点上。
问最少移动总距离。

输入描述

第一行一个整数
接下来一行 个小数,第i个小数表示第i个人的初始位置。
a_i 包含最多五位小数。

输出描述

一行一个小数表示答案。 绝对或相对误差不超过  就算正确。

示例1

输入:

2
0.00000 0.00000

输出:

3.1415926536

示例2

输入:

3
0.00000 120.00000 240.00000

输出:

0.0000000000

原站题解

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

C++14(g++5.4) 解法, 执行用时: 91ms, 内存消耗: 9196K, 提交时间: 2020-02-07 12:23:04

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
#include <algorithm>
#define pi acos(0.0) * 2

using namespace std;

struct node {
    long double pos;
    int v;
    bool operator < (const node &A) const {
        return pos < A.pos;
    }
} a[200001];
int n, cnt;
long double c[100001];

long double calc(long double x) {
    x = x - int((x + 1e-12) / 360) * 360;
    if (x < -1e-12)
        x += 360;
    
    return x;
}

int main() {
    scanf("%d", &n);
    cnt = 0;
    for (int i = 1; i <= n; i++) {
        double x;
        scanf("%lf", &x);
        c[i] = x;
    }
    sort(c + 1, c + n + 1);
    for (int i = 1; i <= n; i++) {   
        a[++cnt].pos = calc(c[i] - (i - 1) * 360. / n); a[cnt].v = 1;
        a[++cnt].pos = calc(c[i] - (i - 1) * 360. / n + 180), a[cnt].v = -1;
    }
    sort(a + 1, a + cnt + 1);
    long double pos = (360 - a[cnt].pos) / 2 + a[cnt].pos, v = 0, res = 0;
    for (int i = 1; i <= n; i++) {
        long double angle = c[i] - pos;
        if (angle < 0) 
            angle += 360;
        if (angle <= 180)
            res += angle, --v;
        else
            res += 360 - angle, ++v;
        pos += 360. / n;
        if (pos >= 360)
            pos -= 360;
    }
    long double ans = res;
    pos = (360 - a[cnt].pos) / 2 + a[cnt].pos - 360;
    for (int i = 1; i <= cnt; i++) {
        res += (a[i].pos - pos) * v;
        ans = min(ans, res);
        v += 2.0 * a[i].v;
        pos = a[i].pos;
    }
    printf("%.10f\n", (double)ans / 180 * pi);
}

C++(clang++11) 解法, 执行用时: 53ms, 内存消耗: 1164K, 提交时间: 2021-04-20 21:25:25

#include<bits/stdc++.h>
using namespace std;

int i,j,n;
double sb[100500],res;

int main()
{
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%lf",&sb[i]);
	}
	sort(sb+1,sb+n+1);
	for(i=1;i<=n;i++){
		sb[i]-=360.0/n*(i-1);
	}
	sort(sb+1,sb+n+1);
	for(i=1;i<=n;i++){
		res+=abs(sb[i]-sb[(i+1)/2]);
	}
	printf("%.20lf",res/180*(double)3.1415926535897932384626);
 } 

pypy3(pypy3.6.1) 解法, 执行用时: 141ms, 内存消耗: 31544K, 提交时间: 2021-05-13 13:45:45

from math import pi
n = int(input())
res = map(float, input().split())
res = list(res)
res.sort()
for i in range(n) :
    res[i] -= 360.0 / n * i
res.sort()
ans = 0
for i in range(n) :
    ans += abs(res[i] - res[n // 2])
print("%.10f" % (ans / 180 * pi))

上一题