acwing周賽52
阿新 • • 發佈:2022-05-15
1.上車
演算法(暴力列舉) \(O(n)\)
只需要判斷出車輛空餘是否大於二即可
時間複雜度
暴力一遍即可,複雜度位\(O(n)\)
C++ 程式碼
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N = 1e5 + 10; int n, m, k; int main() { cin.tie(0); cout.tie(0); ios::sync_with_stdio(0); int cnt = 0; cin >> n; while(n--) { int a, b; cin >> a >> b; if(b - a >= 2) cnt++; } cout << cnt; return 0; }
2.連通分量
演算法(dfs + 模擬) \(O(n^3)\)
題目是找將障礙物假設位空格是的聯通分量的數目
所以我們先預處理將連通塊給找出來,並且將每一個連通塊的數目找出來即可。
時間複雜度
預處理是n*m + 一次深搜, 列舉每一個障礙物是n*m*4,所以時間複雜度最大位\(O(n^3)\)
C++ 程式碼
#include<iostream> #include <set> #include<algorithm> #include<cstring> using namespace std; const int N = 10100; int n, m, k; char a[N][N]; int vis[N][N]; int cnt = 0; int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; int check(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; } int dfs(int x, int y) { vis[x][y] = cnt; //標記是哪個連通塊 int res = 0; for(int i = 0; i < 4; i++) { int tx = x + dx[i], ty = y + dy[i]; if(check(tx, ty) && !vis[tx][ty] && a[tx][ty] == '.') { res += dfs(tx, ty); //計算數目 } } return res + 1; //加上自己 } int main() { int Hash[1000005];//記錄每一個聯通塊的聯通數目 cin >> n >> m; for(int i = 1; i <= n; i++) cin >> a[i] + 1; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(a[i][j] == '.' && !vis[i][j]) { ++cnt; int c = dfs(i, j); Hash[cnt] = c; } } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(a[i][j] == '*') { set<int> umap; //用於去重 umap.clear(); for(int k=0;k<4;k++) { int tx = i + dx[k], ty = j + dy[k]; if(check(tx, ty) && a[tx][ty] == '.' && umap.find(vis[tx][ty]) == umap.end()) umap.insert(vis[tx][ty]); int res = 1; for(auto c : umap) res += Hash[c]; a[i][j] = (res % 10) + '0'; } } } } for (int i = 1; i <= n; i++) cout << a[i] + 1 << endl; return 0; }
3.訊號
演算法(貪心) \(O(n)\)
題目讓我們找最小個數覆蓋全部房子。
分析可得如果我們找到一個覆蓋範圍比前面一個大的,我們就可以選擇後面一個最為一個最值
時間複雜度
一次遍歷即可求出 \(O(n)\)
C++程式碼
#include <iostream> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int N = 1010; int n,r,cnt; int qu[N]; int main() { cin >> n >> r; for(int i= 1; i <= n;i++) { int x; cin >> x; if(x) qu[cnt++]=i; } int last = 0, res = 0; for(int i = 0; i < cnt; i++) { if(last >= n) break; if(qu[i] - r + 1 > last + 1) { res = -1; break; } int j = i; while(j + 1 < cnt && qu[j + 1] - r <= last) j++; last = qu[j] + r - 1; res++; i = j; } if(last >= n) cout << res; else cout << -1; return 0; }