Python “最短”挑战(12.22)

Description

有一组点均匀地分布在在一个周长为10000米的圆上。现在要再添加一些点进去,使得这些点仍均匀分布。如果仅可以沿圆周移动某些点,请你求总移动距离的最小值。

Input

有多行输入,每行两个数字n,m(2<=n<=1000,1<=m<=1000),空格隔开,分别表示原先和要添加的点的数量,当输入0 0时,表示输入结束,程序退出。

Output

总移动距离的最小值,保留4位小数。
其余要求同首题

Sample Input

2 1
2 3
0 0

Sample Output

1666.6667
1000.0000

Reference code

[n1,n2]=list(map(int,input().split(' ')))
while n1 and n2:
    print('%.4f'%sum(abs(i*10000/n1-(i+int(i*n2/n1+0.5))*10000/(n1+n2)) for i in range(n1)))
    [n1,n2]=list(map(int,input().split(' ')))
'''
while True:
    [n1,n2]=list(map(int,input().split(' ')))
    if n1==0 and n2==0:
        break
    ans=0
    x=[i*10000/n1 for i in range(n1)]
    y=[i*10000/(n1+n2) for i in range(n1+n2)]
    for i in range(n1):
        for j in range(n1+n2):
            if y[j]<=x[i]<=y[j+1]:
                ans+=min(x[i]-y[j],y[j+1]-x[i])
    print('%.4f'%ans)
'''

Algorithm Explain

这是一条略有难度的题目,其中的算法在数学上证明需要一点功夫。笔者在这里贴一下自己的解法:
我们将这个圆以其中一点为原点展开成一条线段,线段的左端点放点,右端点不放点。
x i x_i xi表示原来各点的坐标,有
x i = l i n 1 , 0 ⩽ i ⩽ n 1 , i ∈ Z , l = 10000 x_i=l \frac{i}{n_1} , 0 \leqslant i \leqslant n_1 , i \in \mathbb{Z} ,l=10000 xi=ln1i,0in1,iZ,l=10000

y j y_j yj表示之后各点的坐标,有
y j = l j n 1 + n 2 , 0 ⩽ j ⩽ n 1 + n 2 , j ∈ Z y_j=l \frac{j}{n_1+n_2} , 0 \leqslant j \leqslant n_1+n_2 , j \in \mathbb{Z} yj=ln1+n2j,0jn1+n2,jZ

则有
x i − y j = l ( i n 1 − j n 1 + n 2 ) x_i - y_j=l \left(\frac{i}{n_1}-\frac{j}{n_1+n_2} \right) xiyj=l(n1in1+n2j)

要使每一个 i i i ∣ x i − y j ∣ \vert x_i-y_j \vert xiyj最小,则 j j j一定满足以下两种情况之一:
{ x i − y j ⩾ 0 x i − y j + 1 ⩽ 0 ① \left\{ \begin{aligned} x_i - y_j \geqslant 0 \\ x_i - y_{j+1} \leqslant 0 \end{aligned} \right. ① {xiyj0xiyj+10

{ x i − y j − 1 ⩾ 0 x i − y j ⩽ 0 ② \left\{ \begin{aligned} x_i - y_{j-1} \geqslant 0 \\ x_i - y_{j} \leqslant 0 \end{aligned} \right. ② {xiyj10xiyj0

解①得:
j = i + [ n 2 n 1 i ] j=i+\left[ \frac{n_2}{n_1}i \right] j=i+[n1n2i]

解②得:
j = i + [ n 2 n 1 i ] + 1 j=i+\left[ \frac{n_2}{n_1}i \right] +1 j=i+[n1n2i]+1

x i − y j ⩽ y j + 1 − x i x_i - y_{j} \leqslant y_{j+1} - x_i xiyjyj+1xi时取①,否则取②,此时有:
{ n 2 n 1 i } ⩽ 1 2 \left\{ \frac{n_2}{n_1}i \right\}\leqslant \frac{1}{2} {n1n2i}21

则可以得出,对于每一个 i i i,其对应的 j j j为:
j = i + [ n 2 n 1 i ] + [ { n 2 n 1 i } + 1 2 ] = i + [ n 2 n 1 i + 1 2 ] j =i+\left[ \frac{n_2}{n_1}i \right]+\left[\left\{ \frac{n_2}{n_1}i \right\} + \frac{1}{2}\right] \\ =i+\left[\frac{n_2}{n_1}i+\frac{1}{2}\right] j=i+[n1n2i]+[{n1n2i}+21]=i+[n1n2i+21]

但是,此题到这里还并没有结束,仔细思考后我们会发现,如果存在一种情况下, x i x_i xi移向 y j y_j yj x i + 1 x_{i+1} xi+1也移向 y j y_j yj,这会导致两个点重合而存在空缺的点位,最终的总距离偏小。
那么,这种情况是否会存在呢?假设存在这种情况,则有
{ y j + 1 − x i ⩾ x i − y j x i + 1 − y j + 1 ⩾ y j + 2 − x i + 1 \left\{ \begin{aligned} y_{j+1} - x_i \geqslant&amp; x_i - y_{j} \\ x_{i+1} - y_{j+1} \geqslant&amp; y_{j+2} - x_{i+1} \end{aligned} \right. {yj+1xixi+1yj+1xiyjyj+2xi+1

上下相加得:
2 ( x i + 1 − x i ) &lt; y j + 2 − y j 2\left(x_{i+1} - x_i\right) &lt;y_{j+2}-y_j 2(xi+1xi)<yj+2yj


l n 1 &lt; l n 1 + n 2 \frac{l}{n_1}&lt;\frac{l}{n_1+n_2} n1l<n1+n2l

n 2 &lt; 0 n_2&lt;0 n2<0,矛盾!!!
所以这种情况不存在。此题至此结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值