description
还记得上一题那个美术题吗,要在圆心处美观的画一些线,使得线和圆的交点可以等分圆。
这次难度升级了:
在原点处有一个半径为 的圆,在圆上有 个点,现在我们想随意移动这些点,使得它们最后能做到相邻的两个点之间的距离相同。
助教仔细思索了一下……打开了手机微信摇一摇,直接使用魔法把点摇到合适的位置上去了~
现在你想知道,这些点总共最少需要移动多少距离,才能使得他们能把圆 等分。
输入格式
输入第一行为一个整数 ,表示圆上点的个数。
输入第二行包含 个浮点数 ,表示每个点与圆心的连线和y轴正半轴之间的夹角。浮点数最多包含 位小数。
输出格式
输出一个浮点数,表示这些你最少要移动点的距离之和。如果你的答案是 ,标准答案是 ,当且仅当 时,你将通过此题。
贴一下题目
code
-
a[i]数组进行快速排序,i从1到n。
-
数组b[i]=a[i]-i*360.0/n。
-
b[i]快速排序,得到中位数mid。
-
mindist+=fabs(b[i]-mid)。
-
mindist现在是弧度,转化为长度即可。
-
注意mindist 要用long double
-
具体看代码
#include <cfloat>
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define pi 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
void Swap(double& a, double& b)
{
double tmp = a;
a = b;
b = tmp;
}
void quickSort(double* arr, int begin, int end)
{
//如果区间不只一个数
if(begin < end) {
int mid = rand() % (end - begin + 1) + begin;
Swap(arr[begin], arr[mid]);
double pivot = arr[begin]; //将区间的第一个数作为基准数
int i = begin; //从左到右进行查找时的“指针”,指示当前左位置
int j = end; //从右到左进行查找时的“指针”,指示当前右位置
//不重复遍历
while(i < j) {
//当右边的数大于基准数时,略过,继续向左查找
//不满足条件时跳出循环,此时的j对应的元素是小于基准元素的
while(i < j && arr[j] > pivot)
j--;
//将右边小于等于基准元素的数填入右边相应位置
arr[i] = arr[j];
//当左边的数小于等于基准数时,略过,继续向右查找
//(重复的基准元素集合到左区间)
//不满足条件时跳出循环,此时的i对应的元素是大于等于基准元素的
while(i < j && arr[i] <= pivot)
i++;
//将左边大于基准元素的数填入左边相应位置
arr[j] = arr[i];
}
//将基准元素填入相应位置
arr[i] = pivot;
//此时的i即为基准元素的位置
//对基准元素的左边子区间进行相似的快速排序
quickSort(arr, begin, i - 1);
//对基准元素的右边子区间进行相似的快速排序
quickSort(arr, i + 1, end);
}
//如果区间只有一个数,则返回
}
int main()
{
int n;
double* a = NULL;
double* b = NULL;
long double mindist = 0.0;
srand(time(NULL));
// freopen("file.txt", "r", stdin);
cin >> n;
a = new double[n + 1];
b = new double[n + 1];
for(int i = 1; i < n + 1; i++) {
scanf("%lf", &a[i]);
}
quickSort(a, 1, n);
double tmp = 360.0 / n;
for(int i = 1; i < n + 1; i++) {
b[i] = a[i] - i * tmp;
}
quickSort(b, 1, n);
double mid = b[(1 + n) / 2];
for(int i = 1; i < n+1; i++) {
mindist += fabs(b[i] - mid);
}
mindist = (mindist / 180.0) * pi;
printf("%.100Lf\n", mindist);
return 0;
}
/*
2
0 0
*/
summary
- long double格式化输出占位符使用的是 Lf, L必须大写,f无所谓