在ACM竞赛中代码常用小技巧~(持续更新ing)
2019年4月24 Updata
一:使用双指针O(1)的删除字符串
假设我们现在有一个字符串 S,和一个子串 T
S:AAABCBCDC
T:ABC
我们想要将S中所有的T删除。我们可以借助双指针的算法,指针 i 从 0 到 n-1 ,指针 k <= i;
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
char s[N],t[N];
int main()
{
cin >> s ;
cin >> t ;
int k = 0;
for(int i=0; s[i] ; i++){
s[k++] = s[i]; //将 k 指针所指的字符覆盖,然后k++
if( s[k-3]=='a' && s[k-2] == 'b' && s[k-1]== 'c') k-=3;
//如果当前指针 i 指向的字符的前三个元素是 “abc” k指针回溯
}
s[k] = '\0'; //将字符串截断
cout << s << endl;
return 0;
}
输出的答案应该为 ADC
二:在判断回文串时如何将偶数的情况转为奇数
先不插入代码了
思想就是在每两个字符之间插入一个一定不会出现的字符,比如 ‘#’
这样整个字符串的长度就变成了 2S - 1 ;
这样字符串的长度就由偶数变为奇数了,减少了代码量
三:括号匹配区间重叠情况证明
在括号匹配的时候可能会出现上图这种情况 —— 有两段可以匹配的区间,但区间有重叠
我们先给出结论: 可匹配的区间更新为两区间的并集
证明如下:将所有左括号看为 1 , 所有右括号看为 -1
当我们在栈( stack )内模拟这个过程的时候会有两条性质
- 如果括号匹配 则 x + y = 0;
- 在任意时刻 x 都是大于等于 0 的一个值
1. 2.
{ {
x >= 0; y >= 0;
x + y == 0; y + z == 0;
} }
易得 x = y = 0; 从而 z == 0;
故 x + y + z == 0;
并区间匹配;
证毕 (瞎证完成)