其他分享
首页 > 其他分享> > 2021-05-04 Codeforces Global Round 14

2021-05-04 Codeforces Global Round 14

作者:互联网

Be happy
A,B两题的出题速度太慢了,尤其是B题,画了好久的图才知道。

A. Phoenix and Gold

#include <bits/stdc++.h>
using namespace std;

const int N = 110;
typedef long long ll;
typedef pair<int, int> PII;

int t, n, x;
int w[N];

int main()
{
	cin >> t;
	while (t -- )
	{
		ll sum = 0;
		cin >> n >> x;
		for (int i = 1; i <= n; i ++ )
		{
			cin >> w[i];
			sum += w[i];
		}
		if (sum == x)
		{
			puts("NO");
			continue;
		}
		sort(w + 1, w + n + 1);
		sum = 0;
		for (int i = 1; i <= n; i ++ )
		{
			sum += w[i];
			if (sum == x)
			{
				swap(w[i], w[i + 1]);
				break;
			}
			if (sum > x) break;
		}
		puts("YES");
		for (int i = 1; i <= n; i ++ )
			cout << w[i] << ' ';
		puts("");
	}
	return 0;
}

B. Phoenix and Puzzle

把问题分解来看
一个正方形分为三角形只能有两种分法。
一个正方形能分为x2正方形。x为自然数。
比赛的时候还脑抽写了个暴力。
其实除2和4后,判断是不是完全平方数就行。

#include <bits/stdc++.h>
using namespace std;

const int N = 110;
typedef long long ll;
typedef pair<int, int> PII;

int t;
ll n;

int main()
{
	cin >> t;
	while (t -- )
	{
		cin >> n;
		ll ans = 1;
		bool f = 1;
		for (int i = 1; i <= 1e5; i ++ )
		{
			ans = i * i;
			if (ans * 2 == n) break;
			if (ans * 4 == n) break;
			if (ans * 2 > n)
			{
				f = 0;
				break;
			}
		}
		if (f) puts("YES");
		else puts("NO");
	}
	return 0;
}

C. Phoenix and Towers

这题并不难可以做,我还是写的题目太少了。
对方块从小到大排序,然后依次放到当前高度最小的塔中。
证明:因为每个方块高度小于x,而放置进的塔又是当前高度最小的,所以一定能构造成功。
multiset存储从小到大的集合。
记得每次清空集合。erase能删除一个区间的数。
用s.erase(s.begin()) 会快一点。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 50;
typedef long long ll;
typedef pair<int, int> PII;

int h[N];
int t, n, m, x;
multiset<PII> s;

int main()
{
	cin >> t;
	while (t -- )
	{
		cin >> n >> m >> x;
		cout << "YES" << endl;
		s.clear();
		for (int i = 1; i <= m; i ++ ) 
			s.insert({0, i});
		for (int i = 1; i <= n; i ++ )
		{
			cin >> h[i];
			auto p = *s.begin();
			s.erase(p);
			s.insert({p.first + h[i], p.second});
			printf("%d ", p.second);	
		}
		puts("");
	}
	return 0;
} 

D. Phoenix and Socks

题意:给你一些袜子,配对所有的袜子,求最小的花费。
右袜子改为左袜子花费加1,颜色改变花费加1。
假设去除已经匹配的袜子后,左袜子个数大于右袜子,将左袜子中颜色相同的成双的袜子中,拿成一半改为右袜子直到左袜子与右袜子个数相同或已经无法执行这个操作。最后将左袜子与右袜子改成个数相等且颜色配对。

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 50;
typedef long long ll;
typedef pair<int, int> PII;

int t, n, l, r;
int c[N], lcnt[N], rcnt[N];

int main()
{
	cin >> t;
	while (t -- )
	{
		cin >> n >> l >> r;
		for (int i = 1; i <= n; i ++ )
			lcnt[i] = 0, rcnt[i] = 0;
		for (int i = 1; i <= n; i ++ )
		{
			cin >> c[i];
			if (i <= l) lcnt[c[i]] ++;
			else rcnt[c[i]] ++;
 		}
		int ans = 0;
		for (int i = 1; i <= n; i ++ )
		{
			int mn = min(lcnt[i], rcnt[i]);
			l -= mn, r -= mn;
			lcnt[i] -= mn, rcnt[i] -= mn; 
		}
		if (l < r)
		{
			swap(lcnt, rcnt);
			swap(l, r);
		}
		for (int i = 1; i <= n; i ++ )
		{
			int ext = l - r;
			int cando = lcnt[i] / 2;
			int Do = min(ext, cando * 2);
			l -= Do;
			ans += Do / 2;
		}
		ans = ans + (l - r) / 2 + (l + r) / 2;
		cout << ans << endl;
	}
	return 0;
}

标签:typedef,14,袜子,05,int,cin,long,ans,04
来源: https://blog.csdn.net/m0_51250458/article/details/116398909