日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

松鼠聚会(洛谷-P3964)

發布時間:2025/3/17 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 松鼠聚会(洛谷-P3964) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

草原上住著一群小松鼠,每個小松鼠都有一個家。時間長了,大家覺得應該聚一聚。但是草原非常大,松鼠們都很頭疼應該在誰家聚會才最合理。

每個小松鼠的家可以用一個點x,y表示,兩個點的距離定義為點(x,y)和它周圍的8個點(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距離為1。

30%的數據,0 ≤ N ≤ 1000

100%的數據,0 ≤ N ≤ 100000; ?10^9 ≤ x, y ≤ 10^9

輸入輸出格式

輸入格式:

第一行是一個整數N,表示有多少只松鼠。接下來N行,第i行是兩個整數x和y,表示松鼠i的家的坐標

輸出格式:

一個整數,表示松鼠為了聚會走的路程和最小是多少。

輸入輸出樣例

輸入樣例#1:

6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2

輸出樣例#1:

20

輸入樣例#2:

6
0 0
2 0
-5 -2
2 -2
-1 2
4 0

輸出樣例#2:

15

思路:

本題實質是給出 n 個點,找出一個點 x,然后使得其他 n-1 個點到 x 的切比雪夫距離最小,之后求距離和的最小值

而需要求 n 個點切比雪夫距離的和時,由于要窮舉其他 n-1 個點到當前點的距離,即計算:

可以發現,每次計算距離都要取 max,每次都是一個 O(n) 的計算過程,總時間復雜度可達 O(n^2),復雜度太高,而曼哈頓距離只有求和與取絕對值兩種運算,因此我們可以考慮將切比雪夫距離轉化為曼哈頓距離,然后利用前綴和優化,進而降低時間復雜度。

設? 為從 i 到 j 曼哈頓距離,那么有:,復雜度仍是 O(n^2)

進一步化簡,有:

同時以 dis(i,j) 中的一部分? 舉例化簡,有:

若先將橫坐標處理為遞增的,那么易得? 前的部分是可以繼續拆絕對值化簡的, 后的部分是? 的,因此進一步可化簡為:

可以發現上式子是一個前綴和,而? 部分與上式同理,因此我們只需要維護有序狀態下?與 的值即可。

此時,各步驟的時間復雜度如下:

  • 坐標變換:O(n)
  • 前綴和處理:O(n)
  • 枚舉每個點:O(n)
  • 計算一個點的答案:O(log n)

總時間復雜度即為:O(nlog n),相較于之前的 O(n^2),已有了極大的優化。

源代碼

#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long #define Pair pair<int,int> LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; } LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;} LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;} LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; } LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); } LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); } LL LCM(LL x,LL y){ return x/GCD(x,y)*y; } const double EPS = 1E-6; const int MOD = 1000000000+7; const int N = 100000+5; const int dx[] = {0,0,-1,1,1,-1,1,1}; const int dy[] = {1,-1,0,0,-1,1,-1,1}; using namespace std;struct Node {LL x, y; } node[N]; int n, x[N], y[N]; LL sum1[N], sum2[N]; int main() {scanf("%d", &n);for (int i = 1; i <= n; i++) {int a, b;scanf("%d%d", &a, &b);x[i] = node[i].x = a + b;y[i] = node[i].y = a - b;}sort(x + 1, x + n + 1);sort(y + 1, y + n + 1);for (int i = 1; i <= n; i++){sum1[i] = sum1[i - 1] + x[i];sum2[i] = sum2[i - 1] + y[i];}LL res=1ll << 62;for (int i = 1; i <= n; i++) {int pos = lower_bound(x + 1, x + n + 1, node[i].x) - x;LL sum = sum1[n] - sum1[pos] - node[i].x * (n - pos) + node[i].x * pos - sum1[pos];pos = lower_bound(y + 1, y + n + 1, node[i].y) - y;sum += sum2[n] - sum2[pos] - node[i].y * (n - pos) + node[i].y * pos - sum2[pos];res = min(res, sum);}printf("%lld\n", res / 2);return 0; }

?

總結

以上是生活随笔為你收集整理的松鼠聚会(洛谷-P3964)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。