牛客練習賽62

2022-03-01 20:17:32 字數 4077 閱讀 9018

傳送門

沒參加這場比賽,賽後做了下de題,還是寫下題解吧。。。

題意:

牛牛和小青蛙froggy是好朋友。

牛牛有 n 種很大的數,每種數有無限個,牛牛可以從這些數中任選若干個(至少1個),並把它們拼接起來,拼接順序任意,所有可以被這樣拼接起來的數被成為「呱數」。

如果乙個「呱數」還滿足它是 p 的倍數,牛牛稱它為「p-呱數」。

求長度最短的 「p-呱數」 的長度是多少。

若無解則輸出 -1。

\(p\leq 200,n\leq 100。\)

思路:

這個題和這裡的c題有點類似。

最直接的想法就是建圖然後\(bfs\),注意到這個題中狀態空間只有\(o(n\cdot p)\)的大小,所以我們可以在\(o(n\cdot p)\)的狀態空間中跑最短路,最後直接求解就行。

**如下:

code

/*

* author: heyuhhh

* created time: 2020/4/26 10:08:06

*/#include #include #include #include #include #include #include #include #include #include #include #define mp make_pair

#define fi first

#define se second

#define pb push_back

#define sz(x) (int)(x).size()

#define all(x) (x).begin(), (x).end()

#define inf 0x3f3f3f3f

#define local

#ifdef local

#define dbg(args...) do while (0)

void err()

templatevoid err(t a, args...args)

template class t, typename t, typename... a>

void err(const t &arg, const a&... args)

#else

#define dbg(...)

#endif

using namespace std;

typedef long long ll;

typedef pairpii;

//head

const int n = 100 + 5, m = 1e6 + 5;

int n, p;

int w[n];

int dis[n][n << 1];

int pow10[m];

void run()

vector s(n);

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

}auto bfs = [&] () }}

int ans = inf;

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

if (ans == inf) ans = -1;

return ans;

};int ans = bfs();

cout << ans << '\n';

}int main()

這個題還有一種更為簡單的做法,我們注意到每次經過乙個串的過程有點類似於乙個有限自動機,將當前狀態\(p\rightarrow p'\),會消耗一定的代價。

那麼我們預處理出\(f[p_1][p_2]\)表示從模\(p\)為\(p_1\)到達模\(p\)為\(p_2\)的最小代價。之後通過floyd演算法求解兩點間最短路即可。

最後答案為\(f[0][0]\)。

題意:

給乙個 n 個節點 m 條帶權邊的無向連通圖,有 q 次詢問,每次詢問圖中 ki 個互不相同的點,你可以選擇乙個數 x,然後將圖中所有邊權小於等於 x 的邊刪除。求當刪除這些邊後 ki 個點互不連通時,x 的最小值。

思路:

最後一步是挺常見的乙個技巧:將任意兩點的關係轉化為按一定順序排列過後兩點的關係。因為不相鄰兩點的\(lca\)的深度一定不超過中間相鄰兩點的\(lca\),也就是其權值會更小。而我們需要的資訊為權值的最大值,所以此時一定不是最優解。

這個題有點卡常。。存圖時要用鄰接鍊錶來存。

感覺kruskal重構樹關鍵的地方就是在於將邊權的問題轉化為樹上點權的問題,而樹上的某些問題我們就可以通過一些常見的演算法來解決,比如求\(lca\)等等。

**如下:

code

/*

* author: heyuhhh

* created time: 2020/4/26 17:05:11

*/#include #include #include #include #include #include #include #include #include #include #include #define mp make_pair

#define fi first

#define se second

#define pb push_back

#define sz(x) (int)(x).size()

#define all(x) (x).begin(), (x).end()

#define inf 0x3f3f3f3f

#define local

#ifdef local

#define dbg(args...) do while (0)

void err()

templatevoid err(t a, args...args)

template class t, typename t, typename... a>

void err(const t &arg, const a&... args)

#else

#define dbg(...)

#endif

using namespace std;

typedef long long ll;

typedef pairpii;

//head

const int n = 5e5 + 5;

int n, m, q;

int nodes[n], num;

struct edge e[n << 1];

int head[n << 1], tot;

void adde(int u, int v)

vector g[n << 1];

int fa[n << 1], val[n << 1];

int find (int x)

int f[n << 1][20], deep[n << 1], dfn[n << 1], t;

void dfs(int u, int fa)

for (int i = head[u]; i != -1; i = e[i].next)

}int lca(int x, int y)

if(x == y) return x;

for(int i = 19; i >= 0; i--)

return f[x][0];

}void kruskal (vector >& edges)

sort(all(edges), [&] (paira, pairb) );

int cnt = n;

for (int i = 0; i < sz(edges); i++)

}dfs(cnt, 0);

}void run ()

kruskal(e);

int lastans = 0;

while (q--)

sort (nodes + 1, nodes + num + 1, [&](int a, int b) );

int ans = 0;

for (int i = 2; i <= num; i++)

cout << ans << '\n';

lastans = ans;

}}int main()

牛客練習賽9

時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 珂朵莉想每天都給威廉送禮物,於是她準備了n個自己的本子 她想送最多的天數,使得每天至少送乙個本子,但是相鄰兩天送的本子個數不能相同 珂朵莉最多送幾天禮物呢 第一行乙個整...

牛客練習賽15

時間限制 c c 2秒,其他語言4秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 第一次期中考終於結束啦!沃老師是個語文老師,他在評學生的作文成績時,給每位學生的分數都是乙個小於10的非負小數。amy 8.99999999999999999999...

牛客練習賽5

給你n個正整數,n 5,每個正整數大小不超過1000,最初su m 0 sum 0 每次可將su m sum 按順序加上陣列中的數,加完之後可以對sum的數字進行全排列,求最終能達到的最大值。由於n只有5,所以按照題意模擬dfs實現就可以了,注意最後一組也可以按數字進行全排列。d題 include ...