1-万万没想到之聪明的编辑
解题思路
此题的编辑规则如下
- 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
- 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
- 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC
从题目可以看出,本题的规则实际上只有两个,1和2,1是指连续3个同样的字母,则去掉一个;
2是指两对一样的字母,则去掉第二对的一个字母。第3条规则告诉我们规则是从左往右匹配,因此每次我们去掉的字母都将是形成这种规则的最后一个字母。
所以对给定的字符串,先对其执行规则1,再执行规则2。
代码
#include<iostream>
#include<string>
using namespace std;
int main() {
int n;
cin >> n;
while (n--) {
string s;
cin >> s;
//规则1
for (int i = 2; i < s.length(); i++) {
if (s[i] == s[i - 1] && s[i - 1] == s[i - 2]) {
s.erase(i, 1);//满足规则1,删除一个该字符
i--;
if (s.length() < 3) break;
}
}
//规则2
for (int i = 3; i < s.length(); i++) {
if (s[i] == s[i - 1] && s[i - 2] == s[i - 3]) {
s.erase(i, 1);//满足规则2,删除一个该字符
i--;
if (s.length() < 3)break;
}
}
cout << s << endl;
}
}
2-万万没想到之抓捕孔连顺
解题思路
参考自该博客
题目的意思,就是给定一系列已排序的数,从这些数中任选三个数,使其满足最大和最小的数差值小于等于给定值。
我觉得下面该blog的思想有些不对,如果打印出具体的组合将是错误的结果,但是由于其计算组合数的数目是对的,因此产生了正确的结果;
例如下面的输入
输入:
4 3
1 2 3 4
对于blog中的思想,其将产生的组合分别为:
#此时left=0,right=2
1 2 3
#此时left=0,right=3
1 2 3
1 2 4
1 3 4
可以看出组合数量是对的,但真正的组合并没有求对,在right=3时,发生了重复,多了一组,而这组应该为2 3 4
代码
#include<iostream>
#include<vector>
using namespace std;
long long C(long long n) {//计算Cn2的值
return (n - 1) * n / 2;
}
int main() {
int N,D;
while (cin >> N >> D) {
vector<int> arr(N);
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
//固定p_left,移动p_right,如果满足两者之差<=D,则从[p_left+1,p_right]中选择两个,即为存在的个数
long p_left = 0,p_right =2,count = 0;
for (; p_right < N;p_right++) {
while (arr[p_right] - arr[p_left] > D) {
p_left++;
}
count += C(p_right - p_left);
}
cout<<count%99997867;
}
return 0;
}
4-特征提取
解题思路
使用map<pair<int, int>, pair<int, int>>
;//key-特征(x,y)-value-(起点帧的序号,特征计数)
遍历每个帧,加入新特征或者更新已存在特征的帧起点,特征计数
1、如果该特征不存在,则添加该特征到map
2、如果该特征存在
通过判断(当前帧号==特征起点帧号+特征计数),相等表示连续
(1)如果该特征是连续的,特征计数+1;
(2)如果该特征是不连续的,更新特征起点为当前帧号,特征计数+1;
参考自题解
代码
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
int main() {
int n;
cin >> n;//样例数
for (int k = 0; k < n; k++) {
int m;//帧数
cin >> m;
map<pair<int, int>, pair<int, int>> mp;
int maxLen = 1;
for (int i = 0; i < m; i++) {
int t;//本帧特征数
cin >> t;
for (int j = 0; j < t; j++) {
int x, y;
pair<int, int> p;
cin >> p.first >> p.second;
//判断该帧是否存在
//不存在
if (mp.find(p) == mp.end()) {//原本无该特征,添加该特征
mp[p].first = i;//该帧的起点帧
mp[p].second = 1;//该特征初始计数为1
}
//存在
else {
//连续
if (i == mp[p].second + mp[p].first) {
mp[p].second++;
maxLen = max(maxLen, mp[p].second);
}
//不连续
else {
mp[p].first = i;//更新起始帧号
mp[p].second = 1;//更新计数
}
}
}
}
cout << maxLen << endl;
}
return 0;
}