6 1 好題分享小結

2022-03-29 14:14:48 字數 3203 閱讀 7493

我好久沒寫部落格了啊懶惰病上線,這個歡樂的節日聽了ha最強女選手講課,於是決定翹掉地理課寫篇部落格總結一下;

內容大致是中位數,先看一下圓神講課思路(這樣我可以少闡明很多概念)

第乙個就是引例啦:

貨倉選址

我們設在倉庫左邊的所有點,到倉庫的距離之和為p,右邊的距離之和則為q,那麼我們就必須讓p+q的值盡量小。pq,同理,所以當p=q時就是就是全域性的最優解;

排序之後找中位數;

#include using

namespace

std;

int n,a[100010

];int

main()

cout

<< ans <

}

view code

第二題:七夕祭;

題目大意:n行m列,t個感興趣的攤位,

交換相鄰的兩個攤位,使得每行每列中cl感興趣的攤位數量相同,特別注意的是,每一行的第乙個位置和最後乙個位置也是相鄰,判斷是否可行並且輸出需要移動的步數;

對於判斷是否可行,對行來說,如果t無法整除n,那麼行不可能達到目標,如果可以整除,我們的目標就是如何使每行中有t/n個感興趣的攤位;列也是如此,不過兩者一樣,我們就在這裡分析一種情況吧;

我們在這裡回想起一道經典的貪心題目「均分紙牌」:m個人排成一列,每個人手裡若干張牌c【i】,交換相鄰兩個使得每個人手裡的牌的數量相同;

如果可行(總數t整除m),每個人需要得到t/,m張牌,那麼需要的紙牌數為c【i】-t/m;每次i從i+1出拿牌,同時更新i+1,那麼我們的目標就是每個a【i】=c【i】-t/m=0;

另s【i】為a【i】的字首和,

#includeusing

namespace

std;

intmain()

q/=n;

for(int i=1;i<=n;i++)

int ans=0

;

for(int i=1;i<=n;i++)

cout

return0;

}

view code

回到這個題,如果第乙個位置與最後乙個位置相鄰,那麼這是乙個環形的均分紙牌;

我們可以列舉斷點k,但我們不妨分析,a[i]仍為減去t/m後的陣列,當列舉到斷點k,字首和變為s【i】減去s【k】,那麼答案為∑|s【i】-s【k】|,那麼這個答案何時最小呢,就是上道題的貨倉選址,也就是中位數的時候,所以我們不需要列舉k,只需要排序後找中位數作為s【k】;這時就是最優解;

時間複雜度o(nlogn+mlogm);

#includeusing

namespace

std;

#define n 100010

#define ll long long template

inline void read(t &x)

while(isdigit(ch))

x*=f;

}ll n,m,t,x,y,h[n],l[n],f[n];

inline ll calc(ll b[n],

intn)

sort(f+1,f+n+1

);

for(int i=1;i<=n;i++) ans+=abs(f[i]-f[n+1>>1

]);

return

ans;

}int

main()

for(int i=1;i<=n;i++) h[0]+=h[i];

for(int i=1;i<=m;i++) l[0]+=l[i];

if(h[0]%n==0&&l[0]%m==0

)

else

if(h[0]%n==0

)

else

if(l[0]%m==0

)

else printf("

impossible");

return0;

}

view code

最後一道題目啦:動態中位數:

讀入序列,為奇數時,輸出已讀序列中位數;

我們可以建立兩個堆,乙個大根堆乙個小根堆,對於乙個m長度的序列,從小打到1~m/2的放在大根堆,m/2+1~m的我們放在小根堆,這樣每次的小根堆的堆頂就是答案,任何時候如果乙個堆中的序列數過多,就從堆頂取出堆頂插入另乙個堆,每次插入x和中位數比較,如果x大,就插入大根堆,否則插入小根堆;

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

template

inline void read(t &x)

while(isdigit(ch))

x*=f;

}int

t,n,m,x;

vector

g;priority_queue

,greater >q1;

priority_queue

,less >q2;

inline

void add(int

x)

if(x>q1.top()) q1.push(x);

else

q2.push(x);

while(q1.size()>q2.size())

while(q2.size()>q1.size())

}int

main()

printf(

"%d %d\n

",n,(m+1)/2

);

for(int i=0;i)

putchar('\n

');}

return0;

}

view code

君君演算法課堂 好題分享1

tarzan 非常煩數軸因為數軸上的題總是難度非常大。不過他非常喜歡線段,因為有關線 段的題總是不難,諷刺的是在乙個數軸上有 n 個線段,tarzan 希望自己喜歡的東西和討厭的 東西不在一起,所以他要把這些線段分多次帶走,每一次帶走一組,最多能帶走 k 次。其實 就是要把這些線段分成至多 k 組,...

演算法題 慶祝61

牛家莊幼兒園為慶祝61兒童節舉辦慶祝活動,慶祝活動中有乙個節目是小朋友們圍成乙個圓圈跳舞。牛老師挑選出n個小朋友參與跳舞節目,已知每個小朋友的身高h i。為了讓舞蹈看起來和諧,牛老師需要讓跳舞的圓圈隊形中相鄰小朋友的身高差的最大值最小,牛老師犯了難,希望你能幫幫他。如樣例所示 當圓圈隊伍按照100,...

程式設計題 慶祝61

題目 牛家莊幼兒園為慶祝61兒童節舉辦慶祝活動,慶祝活動中有乙個節目是小朋友們圍成乙個圓圈跳舞。牛老師挑選出n個小朋友參與跳舞節目,已知每個小朋友的身高h i。為了讓舞蹈看起來和諧,牛老師需要讓跳舞的圓圈隊形中相鄰小朋友的身高差的最大值最小,牛老師犯了難,希望你能幫幫他。如樣例所示 當圓圈隊伍按照1...