1388 - Graveyard(数论)
2013-12-03 12:06
211 查看
题目链接:1388 - Graveyard
题目大意:在一个周长为10000的圆形水池旁有n个等距离的雕塑,现在要再添加m个雕塑,为了使得n + m个雕塑等距离,需要移动一些雕塑,问如何使得移动的总位移最小,输出最小值。
解题思路:可以将周长展成坐标来看,原来的n个雕塑在x[i] = i / n,而移动过后的位置应该在y[i] = i / (n + m),根据贪心的思想,x[i]肯定要移动到最近的y[j]上,问题就解决了,然后就讨论说会不会有两个雕像移动到同一个位置,大白书里给出了很好的反证法,假设有两个雕塑会移动到同一个位置上,0.5 和1.499999,他们计算过后都会移动到1的位置上去,但是n和m都是小于1000的,即使取得最大值,n + m = 2000, 而圆的周长为10000,所以每两个雕塑之间的距离最小为5。
题目大意:在一个周长为10000的圆形水池旁有n个等距离的雕塑,现在要再添加m个雕塑,为了使得n + m个雕塑等距离,需要移动一些雕塑,问如何使得移动的总位移最小,输出最小值。
解题思路:可以将周长展成坐标来看,原来的n个雕塑在x[i] = i / n,而移动过后的位置应该在y[i] = i / (n + m),根据贪心的思想,x[i]肯定要移动到最近的y[j]上,问题就解决了,然后就讨论说会不会有两个雕像移动到同一个位置,大白书里给出了很好的反证法,假设有两个雕塑会移动到同一个位置上,0.5 和1.499999,他们计算过后都会移动到1的位置上去,但是n和m都是小于1000的,即使取得最大值,n + m = 2000, 而圆的周长为10000,所以每两个雕塑之间的距离最小为5。
#include <stdio.h> #include <stdlib.h> #include <math.h> int main () { int n, m; while (scanf("%d%d", &n, &m) == 2) { double ans = 0; for (int i = 1; i < n; i++) { double pos = (double) i / n * (n + m); ans += fabs( pos - floor(pos + 0.5) )/ (n + m); } printf("%.4lf\n", ans * 10000); } return 0; }
相关文章推荐
- Android中获取应用程序(包)的信息-----PackageManager的使用(一)
- 函数 的 创建
- solr date时间差8小时解决办法
- CS的项目管理是基于多租户理念设计
- redhat vi 命令
- struts.xml配置详解
- 14周作业
- Object-C 学习笔记(八)---面相对象(继承)
- const
- nodejs c++启动过程3
- TUP第31期:《浪潮之巅》吴军“start up新特点及企业发展机遇”全程图文报道
- 时频信号
- TUP第31期将同步视频直播 向《浪潮之巅》吴军提问继续征集中
- 6.MIL采集和实时显示
- 操作系统之磁盘结构笔记
- 手机ip,
- mongodb数据导入导出以及备份恢复
- 【二分】【自适应Simpson】Bridge
- The current identity (NT AUTHORITY\NETWORK SERVICE) does not have write access
- Hungarian notation 匈牙利命名