2020ICPC上海I - Sky Garden

思维

[I-Sky Garden_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海)(重现赛)@hzy0227 (nowcoder.com)](https://codeforces.com/gym/103202/problem/I)

题意

n(1<=n<=500) 个同心圆,半径分别为 1,2,3 ... n

m(1<=m<=500) 条过原点的直线,把一个圆分为大小相同的 2 * m 部分

圆和直线都是路径,路径长为实际的长度,两两路径会有一个交点,求所有两两交点的最短路之和

思路

O(1),O(n),O(n2),O(n3) 都能写,给出一个 O(n2) 的做法

特判!!!,当 m > 1 时两个直线会在圆心有交点,而 m = 1 时圆心没有交点

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> PII;
#define ALL(x) x.begin(),x.end()
#define pb push_back
#define fi first
#define se second
// #define double long double
const double PI = acos(-1.0);
inline ll _read() {
	static ll ans;
	static unsigned int c;
	static bool p;
	for (c = getchar(); c != '-' && (c < '0' || c > '9'); c = getchar());
	if (c == '-') p = false, c = getchar(); else p = true;
	for (ans = 0; c <= '9' && c >= '0'; c = getchar()) ans = ans * 10 + c - '0';
	return p ? ans :-ans;
}

ll n, m;
double ans;
int main() {
	cin >> n >> m;
	for (ll r = 1; r <= n; r++)
	{
		double tmp1 = 0;
		ll cnt = n - r;
		//外圈除自身和直径
		for (ll i = 1; i < m; i++)
		{
			double a = min((double)r * 2, PI * i * r / m) + 1;
			tmp1 += cnt * a + (cnt - 1) * cnt / 2;
		}
		tmp1 *= 2;
		//外圈直径
		ll a = 2 * r + 1;
		tmp1 += cnt * a + (cnt - 1) * cnt / 2;
		//外圈自身
		a = 1;
		tmp1 += cnt * a + (cnt - 1) * cnt / 2;
		tmp1 *= 2 * m;

		//同圈除直径
		double tmp2 = 0;
		for (ll i = 1; i < m; i++)
			tmp2 += 2 * m * min((double)r * 2, PI * i * r / m);
		//同圈直径
		tmp2 += m * 2 * r;
		ans += tmp1 + tmp2;
	}
	if (m > 1)
		ans += (n + 1) * n * m;
	printf("%.10lf\n", ans);
	return 0;
}
posted @   hzy0227  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示