UVAlive 3708 Graveyard(最优化问题)
2024-10-09 19:08:02
题目描述:
在周长10000的圆上,初始等距的放置着n个雕塑,现在新加入m个雕塑,要使得这n+m个雕塑仍然等距,问原来n个雕塑要移动的距离总和的最小值.
原题地址:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15133
分析:将原有的每个雕塑的坐标位置,映射在一个总长为n+m的数轴上,设第一个点的坐标为0,(新的等分点必然有至少有一个和原来n等分的等分点重合,因为等分点可以等距的绕圆周旋转,总可以转到有至少一个重合的,不妨就让这个重合的点是坐标为0的点)从0到n+m-1的每个整数端点为添加雕塑之后每个雕塑的正确位置。pos[i]代表原来的第i个点在新数轴上的坐标,i/n是在总长为1的线段上n等分的第i个点所占的比例,那么在总长为n+m的线段上它的坐标pos[i]=i/n*(n+m).由于第一个雕塑的坐标保持为0,从第二个雕塑开始枚举,判断当前雕塑的坐标距离哪个整数的端点最近(用四舍五入判断,这又是比较精彩实用的技巧),较近的这段距离,即为它所需要移动的距离,用一个变量来累加结果。在这里不可能出现两个雕塑都距离同一个整数端点较近的情况,因为现在有
m+n 个雕塑,每个雕塑之间的间隔为1,而之前只有 n
个雕塑,那么之前的雕塑之间的间隔一定大于1,所以不可能都靠近同一个整数端点。最后将总的移动距离ans转化为在周长为10000的圆上,用
ans/(m+n)*10000 即可。
这道题得注意一个问题,第十三行的floor改成double会WA,我也不知道为啥,搞不清楚!有大神知道的给我留个言,在下面评论一句,不甚感激!
下面给出AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double n,m;
double ans;
while(scanf("%lf%lf",&n,&m)!=EOF)
{
ans=0.0;
for(int i=;i<n;i++)
{
double pos=i/n*(n+m);
ans+=fabs(pos-floor(pos+0.5));
}
ans/=n+m;
printf("%.4lf\n",ans*);
}
return ;
}
最新文章
- webservice4
- C#-WinForm-打开其他窗体的三种方式-Show()、设置Owner()、ShowDialog()
- Java-String类的常用方法总结
- WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
- [设计模式] 16 迭代器模式 Iterator Pattern
- ZigBee HomeAutomation分析
- Java调用SQLCMD遇到的问题
- hdu&;&;poj搜索题题号
- 读书笔记 effective c++ Item 17 使用单独语句将new出来的对象放入智能指针
- java后端学习流程
- MySql 修改外键 支持级联删除
- HTML5新增的标签及使用
- [LeetCode] Set Intersection Size At Least Two 设置交集大小至少为2
- 【MySQL 读书笔记】全局锁 | 表锁 | 行锁
- Netty实战五之ByteBuf
- C#-判断语句(五)
- 【BZOJ1822】[JSOI2010]冷冻波(二分,网络流)
- 学习erlang书籍 - 转
- JavaScript修改元素
- ES6 学习笔记之三 函数参数默认值