- 万万没想到之聪明的编辑
原题目链接
- 长度大于等于3,才可能出现三个连续相同的情况
- 长度大于等于4,才可能出现AABB情况
- 针对这两种情形,只需要将左边的指针回退一步即可.
#include <vector>
#include <string>
#include <iostream>
using namespace std;
class solution{
public:
string checkString(string str)
{
if (str.size()<3)
return str;
int i=0,j=0;
int n=str.size();
while(i<n){
str[j++]=str[i++];
if (j>=3 && str[j-1]==str[j-2] && str[j-2]==str[j-3]) j--;
if (j>=4 && str[j-1]==str[j-2] && str[j-3]==str[j-4]) j--;
}
while(j<n--){
str.erase(j);
}
return str;
}
};
int main()
{
int n;
cin>>n;
string s;
vector<string> strs;
while(n--){
cin>>s;
strs.push_back(s);
}
solution res;
for(auto&x:strs){
cout<<res.checkString(x)<<endl;
}
}
- 万万没想到之抓捕孔连顺
原题目链接
思路:
- 给三个特工选择位置,其实就是一个组合的问题.
- 给定了元素个数n,且是增序排列.将其放入一个数组a中,通过两个指针构建一个滑动窗口.需要满足a[j]-a[i]<=D,这个范围内的元素个数就是m=(j-i+1),但是此时第一个位置已经被选中,所以需要在剩下的位置中任选2,也就是求C(m-1,2).
- 注意: 在循环中滑动窗口是左闭右开,因此可以放置剩下两个特工的长度为:len=(j-i-1)
#include <vector>
#include <iostream>
using namespace std;
class solution{
public:
int count(int n, int d, vector<int>& a)
{
if(n<3){
return 0;
}
long long count=0;
int len=0;
int i=0,j=1; // 左闭右开 [i,j) (j-i)>d
for( ; i<n-2; ++i){ //至少需要三个位置,因此i的最多指向n-3
while(j<n && (a[j]-a[i])<=d){
j++;
}
len=j-i-1; //这表示可以放置另外两个特工的空间长度,我们只需任意挑出两个即可
if(len>=2){
count += (long long)(len-1)*(long long)len/2%99997867;
}
}
return count%99997867;
}
};
int main()
{
int n,d,tmp;
cin>>n>>d;
vector<int> v;
for(int i=0;i<n; ++i){
cin>>tmp;
v.push_back(tmp);
}
solution res;
int m = res.count(n,d,v);
cout<<m<<endl;
}