牛客练习赛 121
牛客练习赛 121
A 小念吹气球
分析
打标记统计一下数量即可
代码
点击查看代码
void solve () {
int n; string s;
cin >> n >> s;
ll cn = 0;
map<char, bool> mp;
for (int i = 0; i < n; i ++) {
if (!mp[s[i]]) {
cn += 2;
mp[s[i]] = true;
} else {
cn ++;
}
}
cout << cn << endl;
return ;
}
B You Brought Me A Gentle Breeze on the Field
分析
首先\(n = 1\)时先手必败,第二种情况是\(2 <= n <= m + 1\),这种情况下先手必胜,因为先手可以直接拿n - 1个,第三种情况则是\(n >= m + 2\),此时有连续机会的人必胜,因为无论初始局面的先手胜负情况如何,其一定可以通过连续机会调换先后手顺序,使自己必胜
代码
点击查看代码
void solve () {
int n, m, k;
cin >> n >> m >> k;
if (n == 1) cout << "YangQiShaoNian" << endl;
else if (n >= 2 && n <= m + 1) cout << "XiaoNian" << endl;
else {
if (k == 0) {
cout << "XiaoNian" << endl;
} else {
cout << "YangQiShaoNian" << endl;
}
}
return ;
}
C 氧气少年的水滴 2
分析
模拟即可,详见代码
代码
点击查看代码
void solve () {
int n, m;
cin >> n >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i ++) cin >> a[i];
if (a[m] < 9) {
cout << 0 << ' ' << 0 << endl;
} else {
ll cn0 = 1, cn1 = 1, l = m - 1, r = m + 1;
while (true) {
bool fl = false;
while (l >= 1 && cn0 > 0 && a[l] < 10) fl = true, a[l] ++, cn0 --;
if (a[l] == 10) cn0 ++, cn1 ++, l --;
while (r <= n && cn1 > 0 && a[r] < 10) fl = true, a[r] ++, cn1 --;
if (a[r] == 10) cn1 ++, cn0 ++, r ++;
if (!fl) break;
}
cout << cn0 << ' ' << cn1 << endl;
}
return ;
}
D 氧气少年的 LCM
分析
可知LCM一定是GCD的倍数,代码中cn即是这个量。然后二进制拆分即可,先把要用到的二进制数全都算出,然后按位加即可
代码
点击查看代码
struct Node{
ll op, a, b;
};
void solve () {
ll x, y; cin >> x >> y;
if (x > y) swap(x, y);
ll g = gcd(x, y);
vector<Node> ans;
ll cn = x * y / g / g;
ans.pb({1, x, y});
ans.pb({1, x, y});
for (ll i = 1; (cn >> i) != 0; i ++) {
ans.pb({2, (1ll << (i - 1)) * g, (1ll << (i - 1)) * g});
ans.pb({2, (1ll << (i - 1)) * g, (1ll << (i - 1)) * g});
}
ll nw = 0;
for (ll i = 0; (cn >> i) != 0; i ++) {
if (cn >> i & 1) {
if (nw == 0) {
nw = (1ll << i) * g;
continue;
}
ans.pb({2, nw, (1ll << i) * g});
nw += (1ll << i) * g;
}
}
cout << ans.size() << endl;
for (auto node : ans)
cout << node.op << ' ' << node.a << ' ' << node.b << endl;
return ;
}
D 氧气少年逛超市 3
分析
简单线性dp
代码
点击查看代码
void solve () {
int n, m, k;
cin >> n;
vector<int> p(n + 1);
for (int i = 1; i <= n; i ++) cin >> p[i];
cin >> m;
vector<int> x(m + 1);
for (int i = 1; i <= m; i ++) cin >> x[i];
cin >> k;
vector<int> y(k + 1);
for (int i = 1; i <= k; i ++) cin >> y[i];
sort(p.begin() + 1, p.end(), greater<int>());
sort(x.begin() + 1, x.end());
sort(y.begin() + 1, y.end(), greater<int>());
vector<vector<double>> f(n + 1, vector<double> (n + 1));
for (int i = 0; i <= n; i ++)
for (int j = 0; j <= n; j ++)
f[i][j] = 1e9;
f[0][0] = 0;
for (int i = 1; i <= n; i ++) {
for (int j = 0; j <= min(i, m); j ++) {
if (j != 0)
f[i][j] = min(f[i][j], f[i - 1][j - 1] + (double)p[i] * x[j] / 100.0);
if (i > j + k)
f[i][j] = min(f[i][j], f[i - 1][j] + p[i]);
else
f[i][j] = min(f[i][j], f[i - 1][j] + max(0, p[i] - y[i - j]));
}
}
double ans = 1e9;
for (int i = 0; i <= m; i ++) ans = min(ans, f[n][i]);
cout << ans << endl;
return ;
}

浙公网安备 33010602011771号