LA 3708 Graveyard

題目鏈接:

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1709

題意:

一個周長爲10000的圓上等距離分佈n個點,新增加m個點, 若使所有m+n 個點等距離的分佈在圓上,求原來n個點的最小移動距離。

分析:

看下樣例,很容易想到是固定一個點不動,移動剩下n1 個點,就是說以這個不動點爲原點,順時針放剩下的n+m1 個點。
起初想啊,算出每個點的距離之後,把這n1 個點跟他相鄰的點都比較一下找個最近的點,後來看了白書的做法, zz選手表示還是覺得很巧妙的。。
他的思想是將這個圓分成n+m 份,這樣最後的n+m 個點就分別佔據着圓上的整數點,我們可以求出原始n 個點的新座標,這樣距離他最近的整數點就是floor(x+0.5) ,把差累加即可。
但是這樣會不會出現兩個原始點對應同一個整數點呢?只有當兩個數的差小於1的時候他們的floor(x+0.5) 纔有可能相等,但是由於我們把n個點均等的放在了n+m 的座標系中,所以任何兩個點的距離肯定是大於1的。
最後把座標還原回來即可。

代碼:

/*************************************************************************
    > File Name: la3708.cpp
    > Author: jiangyuzhu
    > Mail: [email protected] 
    > Created Time: Sat 18 Jun 2016 03:22:49 PM CST
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
typedef pair<int, int>p;
const int maxn = 1e3, mod = 1e9 + 7, oo = 0x3f3f3f3f;
int main (void)
{
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        double ans = 0;
        for(int i = 1; i < n; i++){
            double pos = (double)i / n * (n + m);
            ans += fabs(pos - floor(pos + 0.5));
        }
        ans = ans / (n + m) * 10000;
        printf("%.4f\n", ans);      
    }
}
發佈了211 篇原創文章 · 獲贊 13 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章