2015弱校連萌寒假套題一 題解

2021-06-28 21:44:15 字數 3813 閱讀 9534

題意:有n頭牛,初始情況下都在一起,編號1~n。每次將一群牛按照編號均等分為前後兩部分,後面部分的牛不能多於前面部分的。如果分出了兩頭牛,則這兩頭牛去跳舞,如果分出了一頭牛,則這頭牛不能跳舞,如果分出的牛數量大於2,則繼續分,問跳舞的牛編號乘積之和。

n <= 2200。

題解:考察你會不會遞迴,模擬分解過程即可。時間複雜度o(n)。

**:

#include int n, ans;

void dfs(int l, int r)

int main()

題意:給定n頭牛的座標,求最遠的兩頭牛的編號,保證解唯一。

n <= 500, 0 <= 座標 <= 5000。

題解:列舉兩頭牛,計算距離即可,避免浮點數誤差可以只計算距離的平方。時間複雜度o(n^2)。

**:

#include const int maxn = 500;

int n, x[maxn], y[maxn], ans, xpos, ypos;

int main()

printf("%d %d\n", xpos + 1, ypos + 1);

return 0;

}

題意:有n首曲子,編號1~n,從0時刻開始依次演奏,每首曲子有乙個時長b。有q個詢問,問某個時刻演奏的是第幾首曲子。

n <= 10000, q <= 50000, 總時間t <= 1200000。

題解:計算出每首曲子的起止時間,依次列舉曲子的話時間複雜度為o(nq),超時;

計算出每個時刻演奏的曲子是什麼,每次直接詢問的話時間複雜度為o(t+q),可行;

根據每首曲子的終止時間是單調遞增的從而二分查詢答案的話時間複雜度為o(qlogn),可行。

**:

#include const int maxn = 1e4 + 1;

int n, q, cnt[maxn];

int main()

while(q--)

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

} return 0;

}

題意:有一條長度為l的路,牛牛初始在座標為0的位置,速度為1,每前進1單位距離,可以使速度的變化不超過1,現在限定了n個位置的最高速度,求牛牛在前進到座標為l的位置的過程中最高速度是多少。

l <= 10 ^ 9,n <= 10 ^ 5。

題解:可以考慮先算出被限制點真正的限速,然後相鄰的限制點之間先加速再減速即可,可達到的最高速度為相鄰點限速之和加時間差的一半(可以認為是時間分別用來提高從兩點增加的速度,提高到的最高點)。

被限制點真正的限速可以利用兩遍dp解決,第一遍可以逆著dp,算出向後加速的限速,第二遍順著dp,算出從前加速的限速,取最小值即可。注意隱含的起點與終點。

時間複雜度o(n)。

**:

#include #include using namespace std;

const int maxn = 1e5 + 10;

int n, l, ans;

struct node

} a[maxn];

int main()

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

return 0;

}

題意:有n首曲子,編號1~n,從0時刻開始依次演奏,每首曲子有乙個時長b。有q個詢問,問某個時刻演奏的是第幾首曲子。

n <= 50000, q <= 50000, 總時間t <= 500000000。

題解:計算出每首曲子的起止時間,依次列舉曲子的話時間複雜度為o(nq),超時;

計算出每個時刻演奏的曲子是什麼,每次直接詢問的話時間複雜度為o(t+q),超時;

根據每首曲子的終止時間是單調遞增的從而二分查詢答案的話時間複雜度為o(qlogn),可行。

**:

#include const int maxn = 5e4 + 1;

int n, q, cnt[maxn];

int main()

while(q--)

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

} return 0;

}

題意:有n個區間,選出盡量多的區間互不相交,求區間個數。

n <= 50000。

題解:貪心選取區間即可,按照區間右端點排序,從最左邊開始選擇即可,時間複雜度o(nlogn)。

**:

#include #include using namespace std;

const int maxn = 5e4;

int n, ans;

struct node

} a[maxn];

int main()

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

return 0;

}

題意:有n個點,m條邊,點有點權,邊有邊權,定義兩點間一條路徑的長度為路徑上邊權之和加路徑上點權最大值,詢問k次兩點間的最短距離。

n <= 250, m <= 10000, 權值 <= 100000。

題解:不考慮點權的情況(g)就是直接floyd即可,若考慮點權的情況(f)則需要按照點權遞增的順序依次新增點進入floyd演算法,時間複雜度o(n^3)。

**:

#include #include #include using namespace std;

const int maxn = 251;

int n, m, q, pos[maxn], g[maxn][maxn], f[maxn][maxn];

struct node

} a[maxn];

int main()

sort(a + 1, a + n + 1);

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

pos[a[i].id] = i;

memset(g, 0x3f, sizeof g);

while(m--)

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

g[i][i] = 0;

memset(f, 0x3f, sizeof f);

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

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

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

if(g[i][j] >= g[i][k] + g[k][j])

while(q--)

return 0;

}

題意:有乙個體積為v的揹包,和n組物品,每組物品裡的每個物品有乙個價值和乙個體積,如果要選擇將某個物品放入揹包則還需另外的空間,但同一組的物品只需要乙個額外的空間,求揹包最多能裝多少價值的物品。

n <= 50, v <= 100000, 每組物品數p <= 10, 每個物品的價值 <= 1000000。

題解:按照正常的分組揹包來做即可,每一組是乙個01揹包,如果要選物品則多加乙個額外的物品。時間複雜度o(npv)。

**:

#include const int maxv = 1e5 + 1;

int n, v, f[maxv], g[maxv];

int main()

for(int i = vv; i <= v; ++i)

if(f[i] < g[i])

f[i] = g[i];

} printf("%d\n", f[v]);

return 0;

}

usaco月賽的題目並不難,主要考察思維。

acwing寒假每日一題題解

貨倉選址 頭兩天的每日一題有點水 include using namespace std int s 505 505 int i,j intmain void 語法題蛇形添數 輸入兩個整數n和m,輸出乙個n行m列的矩陣,將數字 1 到 n m 按照回字蛇形填充至矩陣中。具體矩陣形式可參考樣例。輸入格...

acwing 寒假每日一題題解

本篇部落格是基於acwing活動中的寒假每日一題 活動位址 在一條數軸上有 n 家商店,它們的座標分別為 a1 an。現在需要在數軸上建立一家貨倉,每天清晨,從貨倉到每家商店都要運送一車商品。為了提高效率,求把貨倉建在何處,可以使得貨倉到每家商店的距離之和最小。輸入格式 第一行輸入整數n。第二行n個...

寒假每日一題題解 1 24 階乘

n 的階乘 記作 n 是指從 1 到 n 包括 1 和 n 的所有整數的乘積。階乘運算的結果往往都非常的大。現在,給定數字 n,請你求出 n 的最右邊的非零數字是多少。例如 5 1 2 3 4 5 1205 1 2 3 4 5 120,所以 5 的最右邊的非零數字是 2。輸入格式 共一行,包含乙個整...