Educational Codeforces Round 160 (Rated for Div. 2)

发布时间 2023-12-19 13:20:13作者: 加固文明幻景

基本情况

A题秒了。

B题卡了实在太久,BC题最后虽然都过了,但是耗时太久。感觉C对我来说更好写。

B. Swap and Delete

经典+3。

总是一条路偏要走到黑了才会想着换思路,早该换了。

一开始想了一大堆乱七八糟的思路,但都错了。

后面往简单了想,这题毕竟最后必须要左对齐的,直接从左往右比对,从这角度出发想做法,终于想出来了。

我们从左到右逐位处理, 对不用删除的数目 \(t\) 进行统计:

if (s[i] == '0')
{
	if (cnt[1] > 0)
		cnt[1]--, t++; 
	else
    	break;
}
  • 前半部分思路很简单,其实我前面乱试的时候也有想到:

    从左往右比对,如果这一位是 \(0\),那肯定需要 \(1\),如果此时 \(1\) 的数目够,就直接给,然后把不用删除的数目加一。

  • 但是当 \(1\) 的数目不够时,是个难点,我前面没有抓住这个问题:

    事实上,一旦需要的 \(1\) 已经没有了,那么后面所有的数必然都是 \(0\),那么怎样操作都无法让这一位变成 \(1\) 了,只能把后面的数全删了。因此直接退出对不用删的数目的统计,输出答案。

void solve()
{
	std::string s;
	std::cin >> s;
	int n = s.length(), t = 0;//不用删除,只靠移动就可以的数目
	cnt[1] = cnt[0] = 0;
	for (int i = 0; i < n; i++) if (s[i] == '1') cnt[1] ++; else cnt[0]++;
	for (int i = 0; i < n; i++)
	{
		if (s[i] == '0')
		{
			if (cnt[1] > 0)
				cnt[1]--, t++; 
			else
    			break;
		}
		else
		{
			if (cnt[0] > 0)
				cnt[0]--,t++;
            else
				break;
		}
	}
	std::cout << n - t <<std::endl;
}