2022年浙大城市学院新生程序设计竞赛(同步赛)
A. OP (Nowcoder48876 A)
题目大意
输出fengqibisheng, yingyueerlai!
解题思路
python最快
我错了,php
直接打这个字符串就可以了
神奇的代码
print("fengqibisheng, yingyueerlai!")
B. Steel of Heart (Nowcoder48876 B)
题目大意
一个打怪模拟题
解题思路
按照题意模拟即可,用数组维护被动生效时间。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T, typename... rest> void read(T &x, rest&... Rest) { read(x); read(Rest...); } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int la[6]; int main(void) { LL h1, h2; int n; read(h1, h2, n); for(int i = 0; i < 6; ++ i) la[i] = -2000; bool own = false; auto calc = [](LL x){ long long qwq = floor((125 + 1.0 * x * 0.06) * 0.1); return qwq; }; for(int i = 1; i <= n; ++ i){ int m, s, k; scanf("%d:%d", &m, &s); int t = m * 60 + s; read(k); if (k == 1){ h1 += 800; own = true; }else if (k == 2){ h1 += h2; }else{ int target; read(target); if (own && t - la[target] >= 30){ h1 += calc(h1); la[target] = t; } } } write(h1, '\n'); return 0; }
C. Add 9 Zeros (Nowcoder48876 C)
题目大意
给定个数字,问 不是这个数的个数。
解题思路
拿map
或set
记录下出现的数即可。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); set<int> qwq; int n; cin >> n; for(int i = 1; i <= n; ++ i){ int x; cin >> x; qwq.insert(x); } set<int> qaq; for(auto i : qwq){ if (qwq.find(i + 9) == qwq.end()) qaq.insert(i + 9); } cout << qaq.size() << '\n'; return 0; }
D. Cutting with Lines Ⅰ (Nowcoder48876 D)
题目大意
<++>
解题思路
<++>
神奇的代码
E. Cutting with Lines Ⅱ (Nowcoder48876 E)
题目大意
<++>
解题思路
<++>
神奇的代码
F. Survivor (Nowcoder48876 F)
题目大意
名玩家,第 名玩家初始 血,每分钟扣 血,对其实施回复魔法,一次回复 血。
现你可以实施不超过次恢复魔法,问 分钟后存活玩家的最大数量。玩家血量小于等于0即死亡。
解题思路
预处理让第名玩家在 分钟后存活的最少实施回复魔法次数数组 ,从小到大依次恢复直到超过 。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; LL m, k; cin >> n >> m >> k; vector<LL> a(n), b(n), c(n), cnt(n); for(auto &i : a) cin >> i; for(auto &i : b) cin >> i; for(auto &i : c) cin >> i; for(int i = 0; i < n; ++ i){ a[i] -= m * b[i]; if (a[i] <= 0){ cnt[i] = (-a[i] + 1 + c[i] - 1) / c[i]; }else { cnt[i] = 0; } } sort(cnt.begin(), cnt.end()); int ans = 0; while(ans < n){ if (k - cnt[ans] >= 0){ k -= cnt[ans]; ++ ans; }else break; } cout << ans << endl; return 0; }
G. Red Black Tree (Nowcoder48876 G)
题目大意
给定一个直角等腰三角形摆放的格子,初始状态下一些格子颜色为黑色。其余为红色。现在要求将最小数量的红色格子变成黑色,满足以下两个要求:
- 黑色格子的下面两个格子 颜色也必须是黑色
- 两个相邻黑色格子的上一个格子颜色也必须是黑色
问黑色格子数量的最小值。
解题思路
不考虑第二个条件的话,同一列考虑最上面(行号最小)的黑色格子,最终局面就是一些黑色直角等腰三角形的叠加。
加上第二个条件的话,造成的额外影响就是,两个相互覆盖的黑色直角三角形会融合,变成一个更大的直角等腰三角形。
模拟该过程统计答案即可。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; const int N = 1e6 + 8; int maxx[N]; int yy[N], cnt; LL calc(int n){ return 1ll * n * (n + 1) / 2; } int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, k; cin >> n >> k; for(int i = 1; i <= k; ++ i){ int x, y; cin >> x >> y; ++ cnt; yy[cnt] = y; maxx[y] = max(maxx[y], n - x + y + 1); } sort(yy + 1, yy + 1 + cnt); cnt = unique(yy + 1, yy + 1 + cnt) - yy - 1; int l = yy[1]; int r = maxx[yy[1]]; LL ans = 0; for(int i = 2; i <= cnt; ++ i){ if (r >= yy[i]){ r = max(r, maxx[yy[i]]); }else{ ans += calc(r - l); l = yy[i]; r = maxx[yy[i]]; } } ans += calc(r - l); cout << ans << '\n'; return 0; }
H. Beautiful String (Nowcoder48876 H)
题目大意
给定一个字符串,求满足以下任意条件之一的长度为 的各位互不相同的字符串 的数量
- 串从左到右的字母的字典序依次增大,且 (第一个字母)在 出现过
- 串中的字母在串 都出现过。
注意串 和串 都由英文前位小写字母组成。
解题思路
考虑满足第一个条件的字符串个数。
枚举第一个字母,其在出现过,假设是第个英文字母,则剩下位数的方案数就是
考虑满足第二个条件的字母串个数,假设串出现了 种字母,个数就是(阶乘就是排列数) 。
再减去同时满足一二条件的个数,其实就是
因此答案就是
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; #define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i) #define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i) const int N = 18; int cnt[N], n, m; LL jie[20]; LL C(int n, int m){ if (n < m || n < 0 || m < 0) return 0; return jie[n] / jie[m] / jie[n - m]; } LL A(int n, int m){ if (n < m || n < 0 || m < 0) return 0; return jie[n] / jie[n - m]; } int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); jie[0] = 1; FOR(i, 1, N + 1) jie[i] = jie[i - 1] * i; int t; cin >> t; while(t--){ string s; cin >> s >> n; for(auto &i : s) cnt[i - 'a'] ++; LL tmp = 0; int cc = 0; for(int i = 0; i < N; ++ i) if (cnt[i] != 0){ m |= (1 << i); ++ cc; tmp += C(18 - i - 1, n - 1); } tmp -= C(cc, n); tmp += A(cc, n); cout << tmp << '\n'; for(int i = 0; i < N; ++ i) cnt[i] = 0; } return 0; }
I. Digit Problem (Nowcoder48876 I)
题目大意
已知数在二进制下有 个 , 个 ,其差 有 个 。
给一个可能的 。不存在输出
解题思路
构造题从简单入手。
考虑和 的所有 都在高位,此时其没有 。
考虑 的最低位的 往低位移位,则 会多一个 。
此时 的时候可采用该方法构造。
考虑 。
假设 的 个 都在低位,令,可以看成 ,相当于把的高位的 放到最低位,的个数和 一样。
注意的特殊情况。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int a, b, c; cin >> a >> b >> c; if (a + b <= c || (a == 0 && c != 0) || (b == 0 && c != 0)) cout << -1 << '\n'; else{ if (b >= c){ string x(a + b, '0'), y(a + b, '0'); fill(x.begin(), x.begin() + a, '1'); if (a > 0){ fill(y.begin(), y.begin() + a - 1, '1'); y[a + c - 1] = '1'; } cout << x << '\n'; cout << y << '\n'; }else{ string x(a + b, '0'), y(a + b, '0'); fill(x.begin(), x.begin() + a, '1'); fill(y.begin(), y.begin() + a, '1'); y[a + b - c - 1] = '0'; y.back() = '1'; cout << x << '\n'; cout << y << '\n'; } } return 0; }
J. Simple Game (Nowcoder48876 J)
题目大意
个数字,每人每回合拿走一个数字,直至无数字剩下。先手, 后手。最后若两人拿走数的和的差是奇数, A胜,否则 胜。问两者绝顶聪明的情况下谁胜。
解题思路
奇偶性的相加减,也就是模的加减其实等效于异或,即这两个操作是一样的。
因此无论他们怎么拿,最终情况都是一样,即和是奇数就胜,否则 胜。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; int ans = 0; while(n--){ int x; cin >> x; ans ^= (x & 1); } if (ans) cout << "Alice" << '\n'; else cout << "Bob" << '\n'; return 0; }
K. Bit (Nowcoder48876 K)
题目大意
假设当前数为,给定个操作,操作有三种类型:
- 给定 ,令,即与运算。
- 给定 ,令,即或运算。
- 给定 ,令,即异或运算。
有个询问,每个询问给定一个 ,要求从 中选定 一个数,使得该数经过这 个操作后的数最大。
解题思路
注意到位运算,二进制位之间独立,因此依次考虑每个数位取值或 。
预处理数组表示第 位取值为(或 ), 经过这次操作后变成的值。
然后就从高位开始依次考虑每位取值为 或 。取值过程考虑是否有最高位限制(不大过 ),就像数位 里的变量。
即当前位如果可取,且最终值,取 的时候更大,那肯定取 ,否则就取 。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; const int N = 1e5 + 8; int n, q; int f[35][2]; int op[N], num[N]; int cal(int type, int lv, int rv){ if (type == 1) return lv & rv; else if (type == 2) return lv | rv; else return lv ^ rv; } int calc(int pos, int x){ for(int i = 1; i <= n; ++ i){ x = cal(op[i], ((num[i] >> pos) & 1), x); } return x; } int b[32], pos, ans[32]; void dfs(int pos, int limit){ if (pos < 0) return; if (limit && b[pos] == 0){ ans[pos] = 0; dfs(pos - 1, limit && (b[pos] == 0)); } else{ int g1 = f[pos][1]; int g0 = f[pos][0]; if (g1 > g0){ ans[pos] = 1; dfs(pos - 1, limit && (b[pos] == 1)); }else{ ans[pos] = 0; dfs(pos - 1, limit && (b[pos] == 0)); } } } void solve(int r){ pos = -1; while(r){ ++ pos; b[pos] = (r & 1); r >>= 1; } dfs(pos, 1); } int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> q; for(int i = 1; i <= n; ++ i){ cin >> op[i] >> num[i]; } for(int i = 0; i < 30; ++ i){ f[i][0] = calc(i, 0); f[i][1] = calc(i, 1); } while(q--){ int r; cin >> r; solve(r); int val = 0; for(int i = 0; i <= pos; ++ i){ if (ans[i]) val |= (1 << i); } cout << val << '\n'; } return 0; }
L. Elden Ring (Nowcoder48876 L)
题目大意
个人, 各个人围城一个环共两个环。从和 人从 报数,报到的倍数的两人交换位置。问报到时的局面。
解题思路
不大,按题意模拟即可。
神奇的代码
#include <bits/stdc++.h> using namespace std; using LL = long long; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; vector<int> a(n), b(n); iota(a.begin(), a.end(), 1); iota(b.begin(), b.end(), n + 1); int m, k; cin >> m >> k; int pos = 0; int cnt = m; for(int i = 1; i <= k; ++ i){ -- cnt; if (cnt == 0){ swap(a[pos], b[pos]); cnt = m; } ++ pos; if (pos == n) pos = 0; } for(int i = 0; i < n; ++ i) cout << a[i] << ' '; for(int i = 0; i < n; ++ i) cout << b[i] << ' '; return 0; }
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/16972427.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步