Loading

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;
}


比赛链接 https://atcoder.jp/contests/abc382

posted @ 2024-11-30 22:33  _SeiI  阅读(144)  评论(0)    收藏  举报