Educational Codeforces Round 120 (Rated for Div. 2) A ~ C

https://codeforces.com/contest/1622/problem/A

题意:给定三个正整数,将其中一个数分为两个数,判断能否构成长方形。
题解:枚举每种情况就行。

int f[4];
bool cmp(int a, int b)
{
	return a > b;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> f[0] >> f[1] >> f[2];
		sort(f, f + 3,cmp);
		int a = f[0], b = f[1], c = f[2];
 
		if (a == b)
		{
			if (c % 2 == 0)cout << "YES" << endl;
			else cout << "NO" << endl;
		}
		else
		{
			if (a == (b + c))cout << "YES" << endl;
			else
			{
				if (b == c)
					if (a % 2 == 0)cout << "YES" << endl;
					else cout << "NO" << endl;
				else cout << "NO" << endl;
			}
		}
	}
	return 0;
}

https://codeforces.com/contest/1622/problem/B

题意:给定一个数组q,和相同长度的01串,要求1对应的数字必须大于0对应的数字,构造一个数组p,求
在这里插入图片描述
题解:暴力求解即可,首先看有多少个0和1,由于1对应的数都大于0对应的数,所以直接求解原数字排序后的下标,依次按下标填入数据。

const int N = 2e5 + 10;
typedef pair<int, int>PII;
int f[N],ans[N];
 
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		for (int i = 0; i < n; i++) cin >> f[i];
		string res;
		cin >> res;
		int cnt1 = 0, cnt2 = 0;
		vector<PII>v1, v2;
		for (int i = 0; i < res.size(); i++)
		{
			if (res[i] == '0')cnt1++, v1.push_back({ f[i], i });
			else cnt2++, v2.push_back({ f[i], i });
		}
		sort(v1.begin(), v1.end());
		sort(v2.begin(), v2.end());
		for (int i = 1; i <= cnt1; i++)
		{
			ans[v1[i - 1].second] = i;
		}
		for (int i = 1; i <= cnt2; i++)
		{
			ans[v2[i - 1].second] = i + cnt1;
		}
		for (int i = 0; i < n; i++) cout << ans[i] << ' ';
		cout << endl;
		for (int i = 0; i < n; i++) ans[i] = 0;
	}
	return 0;
}

https://codeforces.com/contest/1622/problem/C

题意:给定一个数组,每次可以将某个数-1或者选择两个数,将一个数赋值给另一个数,求解数组的和小于k的最小操作次数。
题解:二分+贪心。首先排序,假设数组长度为n,那么将后n-1个数全部赋值为第一个数,设该操作次数为b,即n-1。剩下的就是将a[0] 减少的次数,设为a,当a<0时,需要改变a,b的值。然后比较b和f[j+1]-f[0]+a的大小(即减少一次赋值,多一次f[0]–的操作,哪个可以将数组的值减少的更多)

const int N = 2e5 + 10;
long long f[N];
long long n, k, sum;
bool check(long long x)
{
	if (sum - x <= k) return true;
	long long a, b, j;
	j = 0;
	b = n - 1;
	a = x - b;
	if (a < 0) b += a, a = 0, j = n - b - 1;
	while (1)
	{
		if (b > 0 && b > (f[j + 1] - f[0] + a)) j++, b--, a++;
		else break;
	}
	long long res = 0, cnm = sum;
	for (int i = n - 1; i > (n - 1) - b; i--)
	{
		cnm = cnm - (f[i] - f[0] + a);
		if (cnm <= k) return true;//防止爆longlong.....巨坑!!!
	}
	cnm -= a;
	if (cnm <= k) return true;
	return false;
}
signed main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		sum = 0;
		for (int i = 0; i < n; i++) cin >> f[i], sum += f[i];
		sort(f, f + n);
		long long l = 0, r = 1e15;
		while (l < r)
		{
			long long mid = l + r + 1 >> 1;
			if (check(mid)) r = mid - 1;
			else l = mid;
		}
		if (check(r)) cout << r << endl;
		else cout << r + 1 << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ja_King_ZH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值