标签:String int ne cin CF st 删去 include 96
D - String Deletion
贪心、链表
要想操作次数最大,设当前已经删到了第 i 个字符,那第一步操作就要找到 i 后面第一个有连续0/1的串,删掉其中一个
- 找到 i 后面第一个有连续0/1的串:将这些可以被删去的位置记录到 set 里,二分找到 i 后面第一个,找到了就删去
- 删去元素后可用链表来维护当前位置的下一个没被删掉的是哪个位置
双指针维护也可以,待补
#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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。