Codeforces Round #650 (Div. 3)

A. Short Substrings

先输出首尾,然后中间的隔一个输出一个。

AC代码:

int main()
{
	int T;
	sd(T);
	while (T--)
	{
		string a, b;
		cin >> b;
		int len = b.size();
		printf("%c", b[0]);
		for (int i = 1; i < len - 1; i += 2)
		{
			printf("%c", b[i]);
		}
		printf("%c\n", b[len - 1]);
	}
	return 0;
}

B. Even Array

计数判断

AC代码:

const int N = 5e5 + 50;
int n, m;
int a[N];
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sd(n);
		int old = 0, even = 0;
		rep(i, 0, n - 1)
		{
			sd(a[i]);
			if ((i % 2) != (a[i] % 2))
			{
				if (a[i] & 1)
					even++;
				else
					old++;
			}
		}
		if (old == even)
			pd(even);
		else
			puts("-1");
	}
	return 0;
}

C. Social Distance

找连续 0 0 0 的个数看看能分成几组。

AC代码;

const int N = 5e5 + 50;
int n, k;
char s[N];
 
int cal(int x)
{
	if (x <= 0)
		return 0;
	int ans = x / (k + 1);
	if (x % (k + 1))
		ans++;
	return ans;
}
 
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sdd(n, k);
		ss(s + 1);
		int ans = 0, last;
		bool flag = false;
		rep(i, 1, n)
		{
			if (s[i] == '1')
			{
				last = i, flag = true;
				break;
			}
		}
		if (!flag)
			ans = cal(n);
		else
		{
			rep(i, 1, k)
				s[++n] = '0';
			s[++n] = '1';
			ans = cal(last - k - 1);
			rep(i, last + 1, n)
			{
				if (s[i] == '1')
				{
					int len = (i - k - 1) - (last + k + 1) + 1;
					ans += cal(len), last = i;
				}
			}
		}
		pd(ans);
	}
	return 0;
}

E. Necklace Assembly

要旋转 k k k 次还能爆出不变说明组成的字符串是一个循环字符串,循环节的长度是 k k k 或者是 k k k 的因子,那么我们就把每个字符的个数统计出来,枚举 k k k 的每个因子,对于这个因子有多少个数大于这个因子的字符 ,二分找循环节的个数。

AC代码:

const int N = 5e5 + 50;
int n, k;
char s[N];
int cnt[N], yz[N];
vector<int> v;
 
bool check(int x, int l)
{
	if (!x)
		return true;
	int res = 0;
	for (auto i : v)
		res += i / x;
	return res >= l;
}
 
int main()
{
	int T;
	sd(T);
	while (T--)
	{
		sdd(n, k);
		ss(s + 1);
		int tot = 0;
		rep(i, 2, k)
		{
			if (k % i == 0)
				yz[++tot] = i;
		}
		mem(cnt, 0);
		v.clear();
		rep(i, 1, n)
			cnt[s[i] - 'a']++;
		rep(i, 0, 25)
		{
			if (cnt[i])
				v.pb(cnt[i]);
		}
		sort(v.begin(), v.end());
		int ans = v.back();
		rep(i, 1, tot)
		{
			int l = 0, r = n, mid, res;
			while (l <= r)
			{
				mid = (l + r) >> 1;
				if (check(mid, yz[i]))
					res = mid, l = mid + 1;
				else
					r = mid - 1;
			}
			ans = max(ans, res * yz[i]);
		}
		pd(ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值