Sky Garden(2020ICPC上海站)

Sky Garden

题目大意

有n个圆他们的圆心都是(0,0),并且第i个圆的半径是i。然后有m条直线将这些圆等分成了2*m分。并且产生了一些交点。让你求任意两个不同的交点之间的最短距离之和是多少。

解题思路

看了大佬的博客看了好久才看明白,解题思路太强了。
首先我们可以知道在一个圆上的所有交点,中任意连个之间的距离肯定是 m i n { 两 点 之 间 的 最 短 弧 长 , 直 径 长 度 } min\left \{两点之间的最短弧长,直径长度\right \} min{}
然后外层圆上的点到内层圆上的点看定时要先进入内层,然后再加上对应的点到内层上点的最短距离就行了。这样层层迭代我们就可以求出答案了;思路说的可能不太清,直接看代码吧;

代码

#include<bits/stdc++.h>
using namespace std;
const int mx=5001;
const double pi=acos(-1);
double a[mx],b[mx];

int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	double cnt=0;
// 一个点到其他一半点的距离不到其对称点的那些点 
	for(int i=1;i<m;i++){
		if(pi*i<2*m){
			cnt+=pi*i/m;
		}else{
			cnt+=2;
		}
	}
// 对称位置的距离	
	cnt*=2;
	cnt+=2;
// a[i] 表示第i个圆到其内部及其这个圆上的所有点的距离和。 
// b[i]	表示第i个圆这个圆其他所有点的距离和。 
	a[1]=b[1]=cnt;
	for(int i=2;i<=n;i++){
// 因为每层圆上的点的距离相当于半径为 1 的圆上的距离怎加了 i 倍。
		b[i]=b[1]*i;
// 之所以加 (i-1)*2*m 是向内层其他点走的时候每个点都有向内走一层。		 
		a[i]=b[i]+a[i-1]+(i-1)*2*m;
	} 
	double ans=0;
	for(int i=1;i<=n;i++){
// 	2*m*(a[i]-b[i]) 表示这层圆上的所有点到内部其他点的距离和
//  m*b[i] 表示的是这层圆上的所有两两不同点的距离和 
		ans+=2*m*(a[i]-b[i])+m*b[i];
//如果m大于1说明中间有交点,
//要求出每个圆上的点到焦点的距离和。		
		if(m>1){
			ans+=2*i*m;
		}
	}
	printf("%.10lf\n",ans); 
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值