intmain(){ string s; while (cin >> s) { string ans = ""; int number = 0; for (char c : s) { if (c >= '0' && c <= '9') { // 遇见数字 number = number * 10 + c - '0'; } else { // 遇见字母 ans += string(number, c); // 添加number个字符c number = 0; } } cout << ans << endl; } }
多多是个游戏高手,总是能操控子弹命中想要命中的敌人。这个游戏—共有 T 个关卡,消灭当前关卡全部敌人后,发射出去多余的子弹会消失,游戏会自动进入下一个关卡。 假设每个关卡都会在屏幕中同时出现N个敌人,这N个敌人所能承受的伤害也已经知道。多多想知道,每个关卡自己最少按几次发射按键就可以将敌人全部消灭。 输入描述 第一行输入一个固定数字T(1<=T=1000)表示关卡的总数量,N(1<=N<=200)表示每个关卡出现的敌人数量。 接下来T行,每行有N个数字D1,D2,…,Dw(1<= Di <= 200)分别表示这N个敌人所能承受的伤害。
intGetInterge(double d){ // 四舍五入 int n = d; double test = n + 0.5; if (d >= test) { return n + 1; } return n; } voidInsertSort(vector<int>& vec, int val){ // 借助二分查找实现插入排序 auto iter = upper_bound(vec.begin(), vec.end(), val); vec.emplace(iter, val); }
intmain(){ int n; while (cin >> n) { vector<int> vec; vector<int> avg(n + 1); vector<int> mid(n + 1); double sum = 0; for (int i = 1; i <= n; i++) { int r; cin >> r; sum += r; avg[i] = GetInterge(sum / i); // 求平均值 InsertSort(vec, r); double tmp = vec[i / 2] + vec[(i - 1) / 2]; mid[i] = GetInterge(tmp / 2); // 求中位数 } // 输出结果 for (int i = 1; i <= n; i++) { cout << avg[i] << " "; } cout << endl; for (int i = 1; i <= n; i++) { cout << mid[i] << " "; } cout << endl; } }
using ll = longlong; const ll kInf = 0xfffffffffffff; intmain(){ ll n, m; while (cin >> n >> m) { vector<vector<ll>> arr(n, vector<ll>(m)); unordered_map<ll, vector<pair<ll, ll>>> ma; for (ll i = 0; i < n; i++) { for (ll j = 0; j < m; j++) { cin >> arr[i][j]; } }
for (ll i = 0; i < n; i++) { for (ll j = 0; j < m; j++) { if (ma.count(arr[i][j]) == 0) { vector<pair<ll, ll>> tmp; tmp.emplace_back(i, j); ma[arr[i][j]] = tmp; } else { ma[arr[i][j]].emplace_back(i, j); } } } vector<vector<ll>> dist1(n, vector<ll>(m, kInf)); vector<vector<bool>> visit1(n, vector<bool>(m, false)); priority_queue<tuple<ll, ll, ll>> qu; dist1[0][0] = 0; qu.emplace(0, 0, 0); while (!qu.empty()) { auto [from_start, i, j] = qu.top(); qu.pop(); if (visit1[i][j]) { continue; } visit1[i][j] = true;
if (i + 1 < n) { ll cur_dist = from_start + abs(arr[i][j] - arr[i + 1][j]); if (dist1[i + 1][j] > cur_dist) { dist1[i + 1][j] = cur_dist; qu.emplace(cur_dist, i + 1, j); } } if (i - 1 >= 0) { ll cur_dist = from_start + abs(arr[i][j] - arr[i - 1][j]); if (dist1[i - 1][j] > cur_dist) { dist1[i - 1][j] = cur_dist; qu.emplace(cur_dist, i - 1, j); } } if (j + 1 < m) { ll cur_dist = from_start + abs(arr[i][j] - arr[i][j + 1]); if (dist1[i][j + 1] > cur_dist) { dist1[i][j + 1] = cur_dist; qu.emplace(cur_dist, i, j + 1); } } if (j - 1 >= 0) { ll cur_dist = from_start + abs(arr[i][j] - arr[i][j - 1]); if (dist1[i][j - 1] > cur_dist) { dist1[i][j - 1] = cur_dist; qu.emplace(cur_dist, i, j - 1); } } } vector<vector<ll>> dist2(n, vector<ll>(m, kInf)); vector<vector<bool>> visit2(n, vector<bool>(m, false)); dist2[n - 1][m - 1] = 0; qu.emplace(0, n - 1, m - 1); while (!qu.empty()) { auto [from_start, i, j] = qu.top(); qu.pop(); if (visit2[i][j]) { continue; } visit2[i][j] = true;
if (i + 1 < n) { ll cur_dist = from_start + abs(arr[i][j] - arr[i + 1][j]); if (dist2[i + 1][j] > cur_dist) { dist2[i + 1][j] = cur_dist; qu.emplace(cur_dist, i + 1, j); } } if (i - 1 >= 0) { ll cur_dist = from_start + abs(arr[i][j] - arr[i - 1][j]); if (dist2[i - 1][j] > cur_dist) { dist2[i - 1][j] = cur_dist; qu.emplace(cur_dist, i - 1, j); } } if (j + 1 < m) { ll cur_dist = from_start + abs(arr[i][j] - arr[i][j + 1]); if (dist2[i][j + 1] > cur_dist) { dist2[i][j + 1] = cur_dist; qu.emplace(cur_dist, i, j + 1); } } if (j - 1 >= 0) { ll cur_dist = from_start + abs(arr[i][j] - arr[i][j - 1]); if (dist2[i][j - 1] > cur_dist) { dist2[i][j - 1] = cur_dist; qu.emplace(cur_dist, i, j - 1); } } } vector<vector<ll>> dist(n, vector<ll>(m, kInf)); ll min_dist = kInf; for (ll i = 0; i < n; i++) { for (ll j = 0; j < m; j++) { auto vec = ma[arr[i][j]]; for (auto [xi, xj] : vec) { if (dist1[i][j] != kInf && dist2[xi][xj] != kInf) { dist[i][j] = min(dist[i][j], dist1[i][j] + dist2[xi][xj]); } } min_dist = min(min_dist, dist[i][j]); } } cout << min_dist << endl; } }
for (int i = 0; i < 4; i++) { int nx = x + dir[i][0], ny = y + dir[i][1]; if (nx < 0 || nx >= n || ny < 0 || ny >= m || v[nx][ny][z] == 1) continue; if (d[nx][ny][z] > dist + abs(a[x][y] - a[nx][ny])) { d[nx][ny][z] = dist + abs(a[x][y] - a[nx][ny]); q.push({d[nx][ny][z], nx, ny, z}); } }
米小游拿到了一个矩阵,矩阵上有一格有一个颜色,为红色( R )。绿色( G )和蓝色( B )这三种颜色的一种。然而米小游是蓝绿色盲,她无法分游蓝色和绿色,所以在米小游眼里看来,这个矩阵只有两种颜色,因为蓝色和绿色在她眼里是一种颜色。米小游会把相同颜色的部分看成是一个连通块。请注意,这里的连通划是上下左右四连通的。由于色盲的原因,米小游自己看到的连通块数量可能比真实的连通块数量少。你可以帮米小游计算连通块少了多少吗?
classUnionFind { // 并查集类 public: UnionFind(int size) { // 初始化 data_ = vector<int>(size); for (int i = 0; i < size; i++) { data_[i] = i; } }
intFind(int k){ // 查找 if (data_[k] == k) { return k; } data_[k] = Find(data_[k]); return data_[k]; } voidUnion(int p, int q){ // 合并 int rootp = Find(p); int rootq = Find(q); data_[rootp] = rootq; } intSize(){ // 连通分量数目 int size = 0; for (int i = 0; i < data_.size(); i++) { if (data_[i] == i) { size++; } } return size; }
private: vector<int> data_; };
intmain(){ int n, m; int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; while (cin >> n >> m) { vector<vector<char>> arr(n, vector<char>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> arr[i][j]; } } // 真实情况连通数量 UnionFind uf1(n * m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int k = 0; k < 4; k++) { int nx = i + dir[k][0]; int ny = j + dir[k][1]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && arr[i][j] == arr[nx][ny]) { uf1.Union(i * m + j, nx * m + ny); } } } } int size1 = uf1.Size(); // 视角连通分量数量 UnionFind uf2(n * m); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int k = 0; k < 4; k++) { int nx = i + dir[k][0]; int ny = j + dir[k][1]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && ((arr[i][j] == 'R') == (arr[nx][ny] == 'R'))) { uf2.Union(i * m + j, nx * m + ny); } } } } int size2 = uf2.Size(); cout << size1 - size2 << endl; } }
#include<bits/stdc++.h> usingnamespace std; voiddfs(vector<vector<char>>& vec, vector<vector<bool>>& visit, int x, int y, char target, int n, int m){ visit[x][y] = true; // 设置成已访问 staticint dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; for (int k = 0; k < 4; k++) { // 遍历四个方向 int nx = x + dir[k][0]; int ny = y + dir[k][1]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && visit[nx][ny] == false && vec[nx][ny] == target) { // 坐标合法,未访问过,为目标值 dfs(vec, visit, nx, ny, target, n, m); } } } intmain(){ int n, m; while (cin >> n >> m) { vector<vector<char>> arr(n, vector<char>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> arr[i][j]; } } vector<vector<bool>> visit1(n, vector<bool>(m, false)); int cnt1 = 0; // 连通分量数目 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (visit1[i][j] == false) { cnt1++; dfs(arr, visit1, i, j, arr[i][j], n, m); } } } // 将蓝色改成绿色 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (arr[i][j] == 'B') { arr[i][j] = 'G'; } } } vector<vector<bool>> visit2(n, vector<bool>(m, false)); int cnt2 = 0; // 连通分量数目 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (visit2[i][j] == false) { cnt2++; dfs(arr, visit2, i, j, arr[i][j], n, m); } } } cout << cnt1 << " " << cnt2 << endl; cout << cnt1 - cnt2 << endl; } }
CPP
第二题
米小游拿到了一个字符串 s 。她可以进行任意次以下两种操作: 1 删除 s 的一个 “mhy” 子序列。 2 添加一个 “mhy” 子序列在 s 上。 例如,给定 s 为 “mhbdy” ,米小游进行一次操作后可以使 s 变成 “bd” ,或者变成 “mhmbhdyy” 。 米小游想知道,经过若干次操作后 s 是否可以变成 t ? 注:子序列在原串中的顺序也是从左到右,但可以不连续。
vector<int> FindSuitNumber(int n, int k, int target){ // [1,n]中选择k个数,总和为target // 等差数列求和公式:Sn = n * (a1 + an) / 2 int min_sum = k * (1 + k) / 2; int max_sum = k * (n - k + 1 + n) / 2; if (target < min_sum || target > max_sum) { // printf("target %d: no suit number\n", target); return {}; } // 如果target属于[min_sum,max_sum],则target一定能取到 vector<int> seq(n); for (int i = 0; i < n; i++) { seq[i] = i + 1; } // 最后数据构成:0...left extra_num right+1...n-1 int left = k - 1; int right = n - 1; int sum = min_sum; int extra_num = -1; while (left >= 0) { int sub = seq[right] - seq[left]; if (sum + sub < target) { // 小于目标值,将右侧元素加入集合 left--; right--; sum += sub; } else { extra_num = seq[left] + target - sum; left--; break; } }
vector<int> ans; for (int i = 0; i <= left; i++) { ans.emplace_back(seq[i]); }
ans.emplace_back(extra_num);
for (int i = right + 1; i < n; i++) { ans.emplace_back(seq[i]); } // 校验结果 int result = accumulate(ans.begin(), ans.end(), 0); if (result != target) { // 总和不为target printf("target: %d result: %d\n", target, result); } if (ans.size() != k) { // 数量错误 printf("wrong ans size: %d", ans.size()); } set<int> se; for (int num : ans) { if (num < 1 || num > n) { // 数字超出范围 printf("wrong value: %d\n", num); } if (se.count(num) > 0) { // 重复数字 printf("repeat value: %d\n", num); } se.emplace(num); }
return ans; }
intmain(){ for (int i = 0; i < 10000; i++) { for (int j = 1; j <= 100; j++) { FindSuitNumber(100, j, i); } } }
intdfs(int cur_id, int cur_value){ cur_value += food[cur_id]; int max_value = cur_value; for (int dst_id : path[cur_id]) { if (max_get[dst_id] == kInf) { max_get[dst_id] = dfs(dst_id, cur_value); } max_value = max(max_value, max_get[dst_id]); } return max_value; }
intmain(){ cin >> n; for (int i = 0; i < n; i++) { int id, parent_id, value; cin >> id >> parent_id >> value; food[id] = value; if (parent_id != -1) { path[parent_id].emplace_back(id); } } int ans = 0; for (int id = 0; id < n; id++) { int tmp = dfs(id, 0); ans = max(ans, tmp); } cout << ans << endl; }