AtCoder Beginner Contest 382
A - Daily Cookie
题意
给定长为\(n\)的串,“.”代表空,“@”代表饼干,一天吃一块饼干,问\(d\)天后有几个格子是空的。
思路
模拟。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
void solve()
{
int n, d;
string s;
cin >> n >> d >> s;
int cnt = count(s.begin(), s.end(), '@');
cout << s.size() - (cnt - d) << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
B - Daily Cookie 2
题意
题意同\(A\),每天吃最右边的饼干,输出最后的情况。
思路
模拟。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
void solve()
{
int n, d;
string s;
cin >> n >> d >> s;
int cnt = 0;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == '@')
{
s[i] = '.';
cnt++;
if (cnt == d)
{
cout << s << endl;
return;
}
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
//cin >> T;
while (T--)
{
solve();
}
return 0;
}
C - Kaiten Sushi
题意
\(n\)个寿司,第\(i\)个寿司有美味度\(b_i\);\(m\)个人,第\(i\)个人有标准\(a_i\)。将寿司放在传送带上,当第\(i\)个人面前经过寿司\(j\)且\(a_i \ge b_j\),他会把寿司吃掉,否则什么都不做。问每个寿司被几号人吃掉,没人吃就输出\(-1\)。
思路
容易发现,当一个人\(i\)前边有人\(j\)且\(a_i \ge a_j\)时,\(i\)永远吃不到寿司,因此能吃到寿司的人就是原序列中的递减子序列。而人的顺序是不能变的,那就将寿司降序排序,如果一个人吃不了当前的寿司,那后边的他都吃不了(a_i < b_j),就看下一个人。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
int n, m;
vector<pii> b;
int _get(int x)
{
int l = 0, r = m;
while (l <= r)
{
int mid = l + r >> 1;
if (b[mid].first >= x)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return l;
}
void solve()
{
cin >> n >> m;
vector<int> a(n), ans(m, -1);
vector<pii> A;
b.resize(m);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
int minn = a[0];
A.push_back({ a[0], 1 });
for (int i = 1; i < n; i++)
{
if (a[i] < minn)
{
minn = a[i];
A.push_back({ a[i], i + 1 });
}
}
for (int i = 0; i < m; i++)
{
cin >> b[i].first;
b[i].second = i;
}
sort(b.begin(), b.end(), greater<pii>());
int now = 0;
for (int i = 0; i < A.size(); i++)
{
int p = _get(A[i].first);
for (int j = now; j < p; j++)
{
ans[b[j].second] = A[i].second;
}
now = p;
}
for (int i = 0; i < m; i++)
{
cout << ans[i] << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
D - Keep Distance
题意
给定\(n\)(\(n\le 12\))、\(m\)(\(10×n-9\le m \le 10×m\)),按字典序输出所有长度为\(n\)的序列\(A\):要求\(A_{i-1} + 10 \le A_i\)且\(1\le A_i\le m\)
思路
\(n\)这么小,
直接跟它爆了!!!考虑一下\(m\)的范围,因为每个数之间相差最少是\(10\),所以当剩下没凑的数的个数\(×10+\)当前枚举到的数超过\(m\)就不用枚举了。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 1e6 + 5;
int n, m;
vector<int> t;
vector<vector<int>> ans;
void dfs(int now)
{
if (t.size() == n)
{
ans.push_back(t);
return;
}
for (int i = now + 10; i + (n - t.size() - 1) * 10 <= m; i++)
{
t.push_back(i);
dfs(i);
t.pop_back();
}
}
void solve()
{
cin >> n >> m;
for (int i = 1; i <= 10; i++)
{
t.push_back(i);
dfs(i);
t.pop_back();
}
cout << ans.size() << endl;
for (auto& v : ans)
{
for (int j = 0; j < v.size(); j++)
{
cout << v[j] << (j == v.size() - 1 ? "\n" : " ");
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
E - Expansion Packs
题意
无限包卡,一包卡有\(n\)张卡,第\(i\)张卡是稀有卡的概率是\(p%\),每张卡是否稀有两两独立。求至少抽出\(x\)张稀有卡时的开包期望。
思路
见代码。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int mxn = 5e3 + 5;
double pf[mxn][mxn]; // 一包卡中前i张卡中抽出j张稀有卡的概率,pf[n][i]就表示一包卡中抽出i张卡的概率
double g[mxn]; // g[i]表示至少出i张稀有卡要抽的次数
void solve()
{
int n, x;
cin >> n >> x;
vector<double> p(n + 1);
for (int i = 1; i <= n; i++)
{
int k;
cin >> k;
p[i] = k * 1.0 / 100;
}
pf[0][0] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
pf[i][j] = pf[i - 1][j] * (1 - p[i]) + (j ? pf[i - 1][j - 1] * p[i] : 0); // 第i张牌不是稀有+第i张牌是稀有
}
}
for (int i = 1; i <= x; i++)
{
double sum = 0, t;
for (int j = 1; j <= n; j++)
{
if (j >= i)
{
continue;
}
sum += pf[n][j] * g[i - j]; // 抽出j张稀有卡的概率*剩下(i-j)要抽出稀有卡的次数
g[i] += g[max(0LL, i - j)] * pf[n][j];
}
g[i] = (sum + 1) / (1 - pf[n][0]); // +1是这次(第i次)抽的一次
}
cout << fixed << setprecision(12) << g[x] << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}


浙公网安备 33010602011771号