2020ICPC上海 I Sky Garden(亂搞,思維)

tomjobs發表於2020-12-17

題意:
在這裡插入圖片描述
就是n個同心圓n條線,第i個圓半徑為i,線平分圓。
求所有交點間最短距離的和。

思路:
看資料範圍很小,所以寫了個 m n 2 mn^2 mn2的演算法,據說可以優化到 O ( n ) O(n) O(n)
很明顯,一個點到另外一個點的最短距離,要麼就是走半徑到圓心,再走半徑到另外一個點;要麼就是小圓上的那個點先走圓周,再走半徑到大圓上的點。

已經知道了最短距離怎麼算了,那麼就直接列舉每一層上的點到其他層上所有點距離和就ok了。

比較噁心的是,我以為原點是一定要有的,所以一開始特判m=1的情況。

#include <algorithm>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>

using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
const double PI = acos(-1);
int main() {
    int n,m;scanf("%d%d",&n,&m);
    double ans = (2 * m + 2 * m * n) * n / 2;
    if(m == 1) ans = 0;
    for(int i = 1;i <= n;i++) {
        double now = 0.0;
        double len = PI * i / m;
        for(int j = i;j <= n;j++) {
            now = 0.0;
            now += j - i;
            for(int p = 1;p <= m - 1;p++) {
                double l1 = len * p + (j - i);
                double l2 = i + j;
                now += min(l1,l2) * 2;
            }
            now += i + j;
            if(j == i) ans += now * m;
            else ans += now * 2 * m;
        }
    }
    printf("%.10f\n",ans);
    return 0;
}

相關文章