S2考前綜合刷題營Day2

2022-02-17 14:18:07 字數 4630 閱讀 8099

一條平直的公路上有 \(n\) 個小路燈,第 \(i\) 個路燈的座標是 \(a_i\)。小 \(a\) 需要把其中的 \(k\) 個點亮,使得每個小路燈與距離最近的被點亮的小路燈的距離的最大值最小。求這個最小值。

第 \(1\) 行 \(2\) 個正整數 \(n,k\)。

接下來 \(n\) 行,每行乙個整數 \(a_i\),表示第 \(i\) 個小路燈的座標,保證 \(a_i\) 是嚴格單調遞增的。

\(1\) 行 \(1\) 個數表示答案。

input

6 356

1219

2027

output
6
點亮第 \(2,5,6\) 個路燈,每個路燈與距離最近的被點亮的路燈的距離分為是 \(1,0,6,1,0,0\),最大值是 \(6\)。可以證明沒有比 \(6\) 更小的方案。

對於 \(30\%\) 的資料,\(n,k≤100\)。

對於 \(100\%\)% 的資料,\(1≤n≤100000\),\(1≤k≤n\),\(|a_i|≤10^9\)。

時間限制:\(1s\)

空間限制:\(512mb\)

30pts

\(n,k<=100\)

考慮用 \(dp\) 來做:\(f[i][j]\) 表示前 \(i\) 個小路燈點亮了 \(j\) 個,且第 \(j\) 個是點亮的,之前每個小路與距離最近的被點亮的小路燈的距離的最大值最小是多少。

\(f[i][j]=\min(\max(f[r][j-1],g(r,i))),0<=r,\(g(r,i)\) 表示第 \(r,i\) 個路燈是被點亮的,\([r,i]\) 內的路燈到最近的被點亮的小路燈的距離的最大值。

時間複雜度 \(o(n^2*k)\)。

100pts

題目要求最大值最小,這一類問題我們通常用二分解決。

我們二分答案 \(mid\) 表示這個最大值是多少,也就是說,現在每個路燈所能照到的範圍就是 \([x-mid,x+mid]\)(因為區間外的路燈會使答案增大),我們只需要判斷是否能照亮小於等於 \(k\) 的路燈使得區間的整體被覆蓋。

貪心思路:如果我們從左往右考慮每個路燈被哪個路燈照亮,那麼一定是所能照到的最靠右的那個路燈。

所以我們可以對於每個路燈,先判斷它已經是否被照亮了,如果沒被照亮,我們就在右側找能照到這個路燈的最靠右路燈。

時間複雜度 \(o(n\log)\)。

#include#include#include#include#define ll long long

using namespace std;

int read()

while(ch>='0'&&ch<='9')

return a*x;

}const int n=1e6+5;

int n,k,l,r;

int a[n];

bool check(int x)

} }return cnt<=k; //所照亮的路燈數小於等於k個就是合法的

}int main()

printf("%d\n",l);

return 0;

}

設數列 \(p=[p_1,p_2,……,p_n]\),定義 \(f(p,k)=[p_2,p_3,……,p_k,p_1,p_,p_,……,p_,p_,……]\),也就是把 \(p\) 每 \(k\) 個分成一段(最後如果不足 \(k\) 個,把它們分到新的一段),然後將每段的首個元素移動到該段末尾。求 \(f(f(……f(f([1,2,……,n],2),3),……),n)\)。

\(1\) 行 \(1\) 個正整數 \(n\) 。

\(1\) 行 \(n\) 個數表示答案。

input

4
output
4 2 3 1
\(p:[1,2,3,4]→[2,1,4,3]→[1,4,2,3]→[4,2,3,1]\)。

對於 \(40\%\) 的資料,\(1≤n≤1000\)。

對於 \(60\%\) 的資料,\(1≤n≤100000\)。

對於 \(100\%\)% 的資料,\(1≤n≤1000000\)。

時間限制:\(2s\)

空間限制:\(512mb\)

40pts

\(n<=1000\)

暴力模擬即可 時間複雜度 \(o(n^2)\)。

60pts

\(n<=100000\)

對序列的插入和刪除一共有 \(\frac+\frac+……+\frac=n*\ln\)

用線段樹或平衡樹維護。

時間複雜度 \(o(n*\log^2)\)。

100pts

\(n<=1000000\)

如果把不動的位置固定,動的位置相當於依次向後移動一位。

每次 \(f\) 作用只會使結尾位置 \(++\)。

什麼意思呢?考慮到每次將若干個長度為 \(k\) 的段的第乙個數插在最後乙個數後面,其實在原序列的位置關係就是這一段的第乙個數挪到了下一段為位置上去,下一段的第乙個數挪到了下下一段為位置上去,...,而最後一段的第乙個數挪到了序列長度 \(+1\) 的位置上去

用乙個 \(2\) 倍長度的陣列就能維護。

時間複雜度 \(o(n*\ln)\)。

#include#include#include#include#include#include#include#define ll long long

using namespace std;

const int n=2e6+5;

int n;

int a[n];

int main()

if(!a[i+n-1]) a[i+n-1]=now;

} for(int i=n;i<2*n;i++) printf("%d ",a[i]);

printf("\n");

return 0;

}

一條平直的公路上有 \(n\) 個路燈,第 \(i\) 個路燈的座標是 \(a_i\)。小 \(a\) 需要把其中的 \(k\) 個點亮,使得每個路燈與距離最近的被點亮的路燈的距離和最小。求這個最小值。

第 \(1\) 行 \(2\) 個正整數 \(n,k\)。

接下來 \(n\) 行,每行乙個整數 \(a_i\),表示第 \(i\) 個路燈的座標,保證 \(a_i\) 是嚴格單調遞增的。

\(1\) 行 \(1\) 個數表示答案。

input

6 356

1219

2027

output
8
點亮第 \(2,4,6\) 個路燈,每個路燈與距離最近的被點亮的路燈的距離和是 \(8\) 。可以證明沒有比 \(8\) 更小的方案。

對於 \(30\%\) 的資料,\(k=2\)。

對於 \(50\%\) 的資料,\(n≤10\)。

對於 \(100\%\) 的資料,\(1≤n≤200\),\(1≤k≤30\),\(k≤n\),\(|a_i|≤50000\)。

時間限制:\(1s\)

空間限制:\(512mb\)

50pts

\(n<=7\)

\(dfs\) 搜尋被點亮的路燈然後取 \(min\)。

時間複雜度 \(o(n*2^n)\)。

100pts

\(n<=200\)

如果你能得且僅得小路燈的 \(30\) 分,那麼你就能得到這道題的滿分。

還是考慮用 \(dp\) 做:\(f[i][j]\) 表示前 \(i\) 個小路燈點亮了 \(k\) 個,且第 \(k\) 個是點亮的,之前每個小路與距離最近的被點亮的小路燈的距離的和最小是多少。

\(f[i][j]=\min(f[r][j-1]+h(r,i))),0<=r,\(h(r,i)\) 表示第 \(r,i\) 個路燈是被點亮的,\([r,i]\) 內的路燈到最近的被點亮的小路燈的距離之和。

時間複雜度 \(o(n^2*k)\)。

#include#include#include#include#include#include#include#define ll long long

using namespace std;

ll read()

while(ch>='0'&&ch<='9')

return a*x;

}const int n=1000;

int n,m;

int a[n],f[n][n],h[n][n];

int main()

while(ch>='0'&&ch<='9')

return a*x;

}const int n=2e5+5;

int n,edge;

int val[n],head[n],fa[n],size[n],dp[n];

ll ans;

struct node

a[n];

void add(int from,int to)

void dfs(int u,int fa)

}int main()

} printf("%lld\n",ans);

return 0;

}

CSP S2考前綜合強化刷題 Day1

阿克掛 240 dk 有 n nn 張牌,奇數屬於第乙個人,偶數屬於第二個人,兩個人輪流按撲克規則進行遊戲。指定乙個先手,求誰能獲勝。以後看見這些簡單的找規律題,一定要從下邊界開始乙個個手玩,不然爆零兩行淚。n 2 n 2 n 2 時顯然誰先手誰獲勝,這是乙個特殊情況,下面預設 n 2n 2 n 2...

Leetcode刷題之旅(Day2)

給出兩個 非空 的鍊錶用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 一位 數字。如果,我們將這兩個數相加起來,則會返回乙個新的鍊錶來表示它們的和。您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。示例 輸入 2 4 3 5 6 4 輸出 ...

演算法刷題 筆記(Day2)

題目描述 判斷乙個整數是否是回文數。回文數是指正序 從左向右 和倒序 從右向左 讀都是一樣的整數。解題思路 一 1.回文數的先決條件x 0.2.利用序列型別資料的性質,先轉字串再進行切片翻轉str 1 題解 class solution def ispalindrome self,x int boo...