ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Beginner Contest 216

2021-09-02 12:34:29  阅读:312  来源: 互联网

标签:216 AtCoder Code Beginner int C++ Sample fa dp


C - Many Balls

初始数字为 \(0\), 你可以选择对这个数进行两种操作:\(A : +1\) 、\(B: *2\),给出一组到达 \(n\) 的操作序列(长度最大 \(120\))。

转化成从 \(n\) 做 \(-1\) 和 \(/2\) 到 \(0\), 偶数做 \(/2\), 奇数做 \(-1\), \(log(10^{18}) \approx 60\), 操作数最多不会超过 \(120\)

Sample Code (C++)
int main()
{
	IOS; LL n; cin >> n;
	vector<char> v;
	while(n)
	{
		if(n & 1) v.push_back('A'), n -= 1;
		else v.push_back('B'), n /= 2; 
	}
	reverse(v.begin(), v.end());
	for(auto c : v) cout << c;
	cout << endl;
	return 0;
} 

D - Pair of Balls

\(n\) 种颜色的球,每种有两个,按一定顺序放在 \(m\) 个瓶子中,若某两个瓶子最上方的两个球颜色相同,则可以同时取掉,问是否可以把球取完。

每种颜色转化成一个点,然后做有向图拓扑判环即可

Sample Code (C++)
int n, m;
vector<int> G[N];
int d[N];

int main()
{
	IOS; cin >> n >> m;
	for(int i = 1; i <= m; ++ i)
	{
		int k, pre = 0; cin >> k;
		for(int j = 1; j <= k; ++ j)
		{
			int x; cin >> x;
			if(pre) G[pre].push_back(x), d[x] ++;
			pre = x;
		}
	}
	queue<int> q;
	for(int i = 1; i <= n; ++ i)
		if(!d[i]) q.push(i);
	int res = 0;
	while(!q.empty())
	{
		int u = q.front(); q.pop(); res ++;
		for(auto v : G[u])
		{
			d[v] --;
			if(!d[v]) q.push(v);
		}
	}	
	if(res == n) cout << "Yes" << endl;
	else cout << "No" << endl;
	return 0;
} 

E - Amusement Park

\(n\) 个数,取 \(k\) 次,每个数取完之后 \(-1\) , 求可以取得的最大值。

贪心从最大的开始取,将 \(a\) 从大到小排序后,判断剩余次数是否够前 \(i\) 个 \(a_i\) 取至 \(a_{i + 1}\) , 分类讨论即可

Sample Code (C++)
LL n, m, a[N];

int main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; ++ i) cin >> a[i];
	LL res = 0;
	sort(a + 1, a + n + 1); reverse(a + 1, a + n + 1);
	for(int i = 1; i <= n; ++ i)
	{
		if((a[i] - a[i + 1]) * i <= m)
		{
			res += (a[i] + a[i + 1] + 1) * (a[i] - a[i + 1]) / 2 * i;
			m -= (a[i] - a[i + 1]) * i;
		}
		else 
		{
			int t = m / i;
			res += t * (a[i] + a[i] - t + 1) / 2 * i;
			res += (m % i) * (a[i] - t); 
			break;
		}
	}
	cout << res << endl;
	return 0;
} 

F - Max Sum Counting

给长度为 \(n\) 的序列 \(A = (A_1, A_2, ..., A_n)\), \(B = (B_1, B_2, ... , B_n)\), 求集合 \(S\) 的方案数,使得:\(\max\limits_{i \in S}A_i\ge \sum\limits_{i \in S}B_i\)

将 \(A\) 按升序排序,每次将当前 \(A_i\) 作为最大的 \(A_i\), 对 \(B\) 做背包统计方案数

Sample Code (C++)
int n;
PII a[N];
int dp[N];

int main()
{
	IOS; cin >> n;
	for(int i = 1; i <= n; ++ i) cin >> a[i].fi;
	for(int i = 1; i <= n; ++ i) cin >> a[i].se;
	sort(a + 1, a + n + 1);
	int res = 0;
	dp[0] = 1;
	for(int i = 1; i <= n; ++ i)
	{
		for(int j = a[i].se; j <= a[i].fi; ++ j)
		{
			res += dp[j - a[i].se];
			if(res > P) res -= P;
		}
		for(int j = 5000; j >= a[i].se; -- j)
		{
			dp[j] += dp[j - a[i].se];
			if(dp[j] > P) dp[j] -= P;
		}
	}
	cout << res << endl;
	return 0;
} 

G - 01Sequence

构造长度为 \(n\) 的 \(01\) 串, 满足 \(m\) 个 \((l, r, x)\) 的限制,即区间 \([l, r]\) 至少有 \(x\) 个 \(1\), 构造一种 \(1\) 最少的方案。

贪心按照右端点排序,并从右端点开始填 \(1\) , 使得填上的 \(1\) 尽可能同时满足多个限制,结合树状数组统计区间 \(1\) 的个数,并查集找最靠右端点的下一个可填 \(1\) 的位置,复杂度 \(O(nlogn)\)

Sample Code (C++)
int n, m, a[N];
struct Node
{
	int l, r, x;
	bool operator < (const Node& t) const 
	{
		return r < t.r;
	}
}q[N];
int fa[N], tr[N];

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

int lowbit(int x) { return x & -x; }

void add(int x) { for(int i = x; i <= n; i += lowbit(i)) tr[i] ++; }

int sum(int x) 
{
	int res = 0; 
	for(int i = x; i; i -= lowbit(i)) res += tr[i]; 
	return res;	
}

int main()
{
	IOS; cin >> n >> m;
	for(int i = 1; i <= n; ++ i) fa[i] = i; 
	for(int i = 1; i <= m; ++ i) cin >> q[i].l >> q[i].r >> q[i].x;
	sort(q + 1, q + m + 1);
	for(int i = 1; i <= m; ++ i)
	{
		int one = q[i].x - (sum(q[i].r) - sum(q[i].l - 1));
		for(int j = 1; j <= one; ++ j)
		{
			int now = find(q[i].r); 
			add(now); 
			a[now] = 1;
			fa[now] = find(now - 1);
		}
	}
	for(int i = 1; i <= n; ++ i) cout << a[i] << " ";
	cout << endl;
	return 0;
}  

标签:216,AtCoder,Code,Beginner,int,C++,Sample,fa,dp
来源: https://www.cnblogs.com/ooctober/p/15218166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有