Codeforces Round 828 (Div. 3) (A~D)

A. Number Replacement

Problem - A - Codeforces

用map记录更改过的位置,如果又遇到要更改的数,就用map检查是不是等于之前改过的字符,不等于就不成立

AC code:

#include<iostream>
#include<map>
#include<string>
using namespace std;
const int manx = 100;
int a[manx];
void solve()
{
	int n;
	cin >> n;
	map<int, int>mp;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	string s;
	cin >> s;
	s = ' ' + s;
	bool flag = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!mp[a[i]])
		{
			mp[a[i]]=i;
		}
		else if (s[i] == s[mp[a[i]]])
		{
			mp[a[i]] = i;
		}
		else
		{
			flag = 0;
			break;
		}
	}
	if (flag)
	{
		cout << "YES" << endl;
	}
	else
	{
		cout << "NO" << endl;
	}
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

B. Even-Odd Increments

Problem - B - Codeforces

不难发现,一个数只有加上奇数他的奇偶性才会发生变化,所以当加的数为奇数时就要维护当前奇数和偶数的奇偶性。

AC code:

#include<iostream>

using namespace std;
const int manx = 2e6 + 10;
typedef long long ll;
ll a[manx];
void solve()
{
	ll n, q;
	cin >> n >> q;
	ll cnt1 = 0, cnt2 = 0;
	ll sum = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		if (a[i] % 2 == 0)
		{
			cnt2++;
		}
		else
			cnt1++;
		sum += a[i];
	}
	while (q--)
	{
		ll k, add;
		cin >> k;
		if (k == 0)
		{
			cin >> add;
			if (add % 2 == 0)
			{
				ll cnt = add * cnt2;
				sum += cnt;
			}
			else
			{
				ll cnt = add * cnt2;
				cnt1 += cnt2;
				cnt2 = 0;
				sum += cnt;
			}
		}
		else
		{
			cin >> add;
			if (add % 2 == 0)
			{
				ll cnt = add * cnt1;
				sum += cnt;
			}
			else
			{
				ll cnt = add * cnt1;
				cnt2 += cnt1;
				cnt1 = 0;
				sum += cnt;
			}
		}
		cout << sum << endl;
	}
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

C. Traffic Light

Problem - C - Codeforces

题意就是找到可以绿灯通行的最大可能时间,由于是循环数组,所以我们可以把该字符串复制两遍,然后从后往前找

AC code:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
void solve()
{
	int n; char k;
	cin >> n>>k;
	string s;
	cin >> s;
	s = ' ' + s + s;
	int ans = 0;
	int last = 0;
	for (int i = 2 * n; i >= 1; i--)
	{
		if (s[i] == 'g')
		{
			last = i;
		}
		else if (s[i] == k)
		{
			ans = max(ans, last - i);
		}
	}
	cout << ans << endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

D. Divisibility by 2^n

https://codeforces.com/contest/1744/problem/D

题意就是数组里的数乘起来要能整除2^n,你可以用一次操作使得ai*i,问最少操作数可以满足题意,如果不能就输出-1。

题意很容易理解,我们可以先计算出数组中用多少个2因子,看看2因子加起来有没有大于n,没有的话就计算下标所含的2因子数,然后贪心,可以用大根堆来存储。

AC code:

#include<iostream>
#include<queue>
#include<string>
using namespace std;
const int manx = 2e6 + 10;
int a[manx];
priority_queue<int>q;
int k = 0;
int cnt(int x)
{
	int ans = 0;
	while (x%2==0)
	{
		ans++;
		x = x / 2;
	}
	return ans;
}
void solve()
{
	while (!q.empty())
	{
		q.pop();
	}
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		a[i] = cnt(a[i]);
		q.push(cnt(i));
	}
	long long sum = 0;
	for (int i = 1; i <= n; i++)
	{
		sum += a[i];
	}
	if (sum >= n)
	{
		cout << 0 << endl;
	}
	else
	{
		int ans = 0;
		while (sum<n&&!q.empty())
		{
			sum += q.top();
			q.pop();
			ans++;
		}
		if (sum < n)
		{
			cout << -1 << endl;
		}
		else
		{
			cout << ans << endl;
		}
	}
}
int main()
{
	
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值