牛客小白月赛105 题解
A. lz的吃饭问题
print("lz" if (lambda a,b: a*b)(*map(int, input().split())) < (lambda a,b: a*b)(*map(int, input().split())) else "gzy")
B. lz的数字问题
把数字按字符串处理,找到小数点则分成整数和小数两段;没有小数点则整个字符串都赋给整数部分,小数部分为空串。得到
string a, b; cin >> a >> b;
// 处理数字a
int n = a.size(); string a1, a2; // 整数、小数部分
for (int i = 0; i < n; i++)
if (a[i] == '.') a1 = a.substr(0, i), a2 = a.substr(i + 1, min(n - i - 1, 6));
if (a1.empty()) a1 = a;
while (a2.size() < 6) a2 += '0';
// 处理数字 b
int m = b.size(); string b1, b2;
for (int i = 0; i < m; i++)
if (b[i] == '.') b1 = b.substr(0, i), b2 = b.substr(i + 1, min(m - i - 1, 6));
if (b1.empty()) b1 = b;
while (b2.size() < 6) b2 += '0';
// 输出答案
cout << ((a1 == b1 && a2 == b2) ? "YES\n" :"NO\n");
C. lz的蛋挞问题
注意到对于一个位于第一行的白色格子,只有 4 种情况下,把它变黑可以增加连通块数目:
- 右侧、下方是白色,右下角是黑色;
- 左侧、下方是白色,左下角是黑色;
- 左右两边是白色,下方是黑色;
- 左右下都是黑色。
对于第二行的格子,把“下方“改成上方即可,用二维数组搭配 i^1
切换上下可以统一。对于边缘的格子,可以在两头各加上一列黑色格子,方便处理边界情况。
for (int i = 0; i <= 1; i++) {
scanf("%s", s[i] + 1);
s[i][0] = s[i][n + 1] = 'x';
}
int ans = 0;
for (int i = 0; i <= 1; i++) {
for (int j = 1; j <= n; j++) {
if (s[i][j] == 'x') continue;
if (s[i][j - 1] == '.' && s[i][j + 1] == '.' && s[i ^ 1][j] == 'x') ans++
else if (s[i][j + 1] == '.' && s[i ^ 1][j] == '.' && s[i ^ 1][j + 1] == 'x') ans++;
else if (s[i][j - 1] == '.' && s[i ^ 1][j] == '.' && s[i ^ 1][j - 1] == 'x') ans++;
else if (s[i][j - 1] == 'x' && s[i][j + 1] == 'x' && s[i ^ 1][j] == 'x') ans++;
}
}
printf("%d\n", ans);
D. lz的染色问题
对于
int count(vector<int>& v) { // 求众数个数
sort(v.begin(), v.end(), [&](int i, int j) { return c[i] < c[j]; }); // 排序,同种颜色的变成连续段
int mxcnt = 1, cnt = 1;
for (int i = 1; i < v.size(); i++)
if (c[v[i]] == c[v[i - 1]]) cnt += 1;
else mxcnt = max(mxcnt, cnt), cnt = 1;
return max(mxcnt, cnt); // 注意处理最后一段
}
int main() {
int n, m, ans = 0; cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> c[i], pa[i] = i;
while (m--) {
int x, y; cin >> x >> y;
int px = find(x), py = find(y);
if (px != py) pa[px] = py;
}
map<int, vector<int>> mp;
for (int i = 1; i <= n; i++) mp[find(i)].push_back(i); // 要求同种颜色的放在一起
for (auto& [i, v] : mp) ans += v.size() - count(v); // 都变成众数最优
cout << ans << '\n';
}
E. lz的括号问题
一个括号序列可以分成几个合法的括号序列,比如 ((()))(())
可以分成 ((()))
和 (())
。自己所在的序列之外的其它括号,显然都可以在自己前面匹配掉;而自己所在的序列中,这个括号之间的括号都可以在它之前匹配掉。把这两部分加起来就是该括号的答案。
更简单的做法是在弹栈之后看看栈里还有
for (int i = 1; i <= n * 2; i++)
if (s[i] == '(') st.push(i);
else if (st.empty()) return puts("-1"), 0;
else cnt[st.top()] = st.size(), st.pop();
if (!st.empty()) return puts("-1"), 0;
for (int i = 1; i <= n * 2; i++)
if (s[i] != ')') printf("%d ", n - cnt[i]);
F. lz的序列问题
线段树,考虑如何合并这个前缀积和
using Mod = ModInt<LL, 1000000007>; // 用了模数类
const int N = 1e5 + 10;
int n, q, a[N];
struct segtree {
int l, r;
Mod sum, prod, tag;
} t[N << 2];
#define ls p << 1
#define rs p << 1 | 1
#define mid ((t[p].l + t[p].r) >> 1)
inline Mod power(Mod a, int n); // 快速幂(略)
inline void refresh(int p) {
t[p].prod = t[ls].prod * t[rs].prod;
t[p].sum = (t[ls].sum + t[ls].prod * t[rs].sum);
}
void build(int p, int l, int r);
inline void pushup(int p, Mod v) {
t[p].tag = v;
int len = t[p].r - t[p].l + 1;
t[p].prod = power(v, len);
t[p].sum = (v == 1) ? len : (power(v, len + 1) - v) / (v - 1); // 注意公比q=1时不能用公式(除0)
}
inline void pushdown(int p) {
if (t[p].tag == 0) return;
pushup(ls, t[p].tag);
pushup(rs, t[p].tag);
t[p].tag = 0;
}
void fill(int p, int l, int r, Mod v) {
if (l <= t[p].l && t[p].r <= r) return pushup(p, v), void(0);
pushdown(p);
if (l <= mid) fill(ls, l, r, v);
if (r > mid) fill(rs, l, r, v);
refresh(p);
}
Mod get_prod(int p, int l, int r) {
if (l <= t[p].l && t[p].r <= r) return t[p].prod;
pushdown(p);
Mod res = 1;
if (l <= mid) res = res * get_prod(ls, l, r);
if (r > mid) res = res * get_prod(rs, l, r);
return res;
}
Mod get_sum(int p, int l, int r) {
if (l <= t[p].l && t[p].r <= r) return t[p].sum;
pushdown(p);
if (l > mid) return get_sum(rs, l, r); // 注意不要写反ls,rs
if (r <= mid) return get_sum(ls, l, r);
return (get_sum(ls, l, r) + get_prod(ls, l, r) * get_sum(rs, l, r));
}
int main() {
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
while (q--) {
int op, l, r; Mod x;
cin >> op;
if (op == 1) {
cin >> l >> r >> x;
fill(1, l, r, x);
} else if (op == 2) {
cin >> l >> r;
cout << get_sum(1, l, r) << endl;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异