其他分享
首页 > 其他分享> > CF EDU 96 D - String Deletion

CF EDU 96 D - String Deletion

作者:互联网

D - String Deletion

贪心、链表

要想操作次数最大,设当前已经删到了第 i 个字符,那第一步操作就要找到 i 后面第一个有连续0/1的串,删掉其中一个

  1. 找到 i 后面第一个有连续0/1的串:将这些可以被删去的位置记录到 set 里,二分找到 i 后面第一个,找到了就删去
  2. 删去元素后可用链表来维护当前位置的下一个没被删掉的是哪个位置


    双指针维护也可以,待补
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n;
int ne[N], fr[N];
bool st[N];
string s;
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> s;
		s = " " + s;
		for (int i = 1; i <= n; i++)
			ne[i] = i + 1, fr[i] = i - 1;
		set<int> del;
		fill(st, st + n + 2, false);
		for (int i = 1; i <= n; i++)
		{
			if (s[i] == s[i+1])
				del.insert(i);
		}
		int cnt = 0;
		for (int i = 1; i <= n; i = ne[i])
		{
			cnt++;
			auto it = del.lower_bound(i);
            //第一步
			if (it != del.end())
			{
				int t = *it;
				del.erase(it);
				int x = fr[t], y = ne[t];
				ne[x] = y, fr[y] = x;
				st[t] = true;
				it++;
			}
			else
				i = ne[i];
			if (i > n)
				break;
            //第二步
			while(s[i] == s[ne[i]])
				i = ne[i];
		}
		cout << cnt << endl;
	}
	return 0;
}

标签:String,int,ne,cin,CF,st,删去,include,96
来源: https://www.cnblogs.com/hzy717zsy/p/16330914.html