1.描述:
A string a=a1a2…an is called even if it consists of a concatenation (joining) of strings of length 2 consisting of the same characters. In other words, a string a is even if two conditions are satisfied at the same time:
一个字符串a是偶数串当它由相同字符组成的长度为2的字符串串联(连接)而成,换句话说,一个字符串是偶数字符串如果同时满足以下两个条件
1.its length n is even;
1.它的长度 n 是偶数
2.for all odd i (1≤i≤n−1), ai=ai+1 is satisfied.
2.对于所有的奇数字母 i 满足 ai = ai + 1;
For example, the following strings are even: “” (empty string), “tt”, “aabb”, “oooo”, and “ttrrrroouuuuuuuukk”. The following strings are not even: “aaa”, “abab” and “abba”.
例如:接下来的字符串是偶数字符串," "(空串),“tt”, “aabb”, “oooo”, and “ttrrrroouuuuuuuukk”.接下来的字符串不是偶数字符串,“aaa”, “abab” and “abba”.
Given a string s consisting of lowercase Latin letters. Find the minimum number of characters to remove from the string s to make it even. The deleted characters do not have to be consecutive.
给出一个包含小写拉丁字母的字符串,找到需要把字符串变成偶数字符串需要移除的最小字母数,删除的字符不必是连续的。
2. 输入:
The first line of input data contains an integer t (1≤t≤104) —the number of test cases in the test.
The descriptions of the test cases follow.
Each test case consists of one string s (1≤|s|≤2⋅105), where |s| — the length of the string s. The string consists of lowercase Latin letters.
It is guaranteed that the sum of |s| on all test cases does not exceed 2⋅105.
3.输出:
For each test case, print a single number — the minimum number of characters that must be removed to make s even.
4.样例输入:
6 aabbdabdccc zyx aaababbb aabbcc oaoaaaoo bmefbmuyw
5.样例输出:
3 3 2 0 2 7
6.题目大意:
给出一个字符串,要把它变成一个偶数字符串。
7.思路
用贪心的思想,从左往右找,每找到一对可配对的就进配对,然后把前边未配对的都删掉
例如:
oaoaaaoo
位置1的o和位置3的o配对,位置2的a被删去,
位置4的a和位置5的a配对
位置7的o和位置8的o配对,位置6的a被删去
我们可以简单证明一下贪心策略的正确性:
1.adda
首先是这种要配对的元素之间有配对好的元素的情况,这种情况按照贪心策略就是删去dd,让aa配对,删去两个元素,我们如果让dd配对,那就要删去aa,删去元素个数相同,不影响结果。
同理
adcffttcda这个串,无论留下那一对偶数串最后的结果和贪心结果(删去个数)都是相同的
2.adad
其次考虑一下这种配对删去元素对后续配对有影响的情况,a和a配对删去d会对下一次d配对产生影响,但是容易看出这个串无论怎么配对其处理结果和贪心结果(删去个数)也都是相同的。
3,aspca
最后是这种最简单的情况,就是配对元素之间的元素无法跟任何元素配对,直接删去就好。
故经过我们简单的证明,可以用贪心来做
8.代码
#include<bits/stdc++.h> using namespace std; map<char,int>mp; string s; int n; int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>s; int len=s.size(),cnt=len; for(int i=0;i<len;i++) { mp[s[i]]++;//计数 if(mp[s[i]]==2) { cnt-=2;//有一个字母配对成功,减去这个字母的长度 mp.clear(); //清空前面字母的影响 } } mp.clear(); //清空map cout<<cnt<<endl;//所有字母减去可配对的就是要删去的 } return 0; }
9.反思
注意这种贪心策略的写法,这种模拟的写法非常值得学习