题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5597
题意:
给出一个长度为n的字符串,B和W分别表示黑棋和白棋。如果白棋旁边有两个黑棋,则可以消去两个黑棋子(BWB),得两分。
同理,如果黑棋子旁边有两个白棋子(WBW),则可以消去两个白棋子,得2分。问最多可以得多少分。
思路:
如果字符串中遇到BBB,WWW,BBBBB这种连续奇数个为相同字母的情况,可以预先处理,因为这种情况最后一定只剩一个B或W。
同理,如果字符串中遇到BBBB,WWWW,WWWWWW这种连续偶数个为相同字母的情况,也可以预先处理,因为这种情况最后一定只剩下2个BB或者两个WW。
所以要考虑的一般情况就是最多只有连续两个相同字母的情况。
如BBWBBWWBBWWBBW。
假设剩下的全部都是连续两个相同字母(除头和尾),如BBWWBBWWBBWW或者BWWBBWWB,那么剩下的一个也不能消去。答案就是总数-剩下的数量。
如果剩下除头和尾中间存在单个的。如BWWBWWBBW。考虑剩下长度的奇偶性。因为预处理是2个2个消,所以剩下长度与n的奇偶性相同,判断n的奇偶性即可。
如果长度为偶数,那么最终肯定会剩下2个,答案是n-2.
如果长度为奇数,那么最终肯定会剩下1个,答案是n-1.
1 #include <bits/stdc++.h> 2 using namespace std; 3 string s; 4 int T, n; 5 struct Node 6 { 7 char c; int cnt; 8 Node(char cc, int ccnt) 9 { 10 c = cc; cnt = ccnt; 11 } 12 Node(){} 13 }node[210]; 14 int main() 15 { 16 scanf("%d", &T); 17 while(T--) 18 { 19 scanf("%d", &n); 20 cin>>s; 21 int res = 0; 22 for(int i = 0; i < s.size(); i++) 23 { 24 if(i == 0) 25 { 26 res++; 27 node[res].cnt = 1; 28 node[res].c = s[i]; 29 } 30 else 31 { 32 if(s[i] != s[i-1]) 33 { 34 res++; 35 node[res].cnt = 1; 36 node[res].c = s[i]; 37 } 38 else node[res].cnt++; 39 } 40 } 41 bool ifone = false; 42 for(int i = 1; i <= res; i++) 43 { 44 if(node[i].cnt%2) node[i].cnt = 1; 45 else node[i].cnt = 2; 46 } 47 for(int i = 2; i <= res-1; i++) 48 { 49 if(node[i].cnt == 1){ifone = true; break;} 50 } 51 if(ifone) 52 { 53 if(n%2 == 0) printf("%d ", n-2); 54 else printf("%d ", n-1); 55 } 56 else 57 { 58 int tot = 0; 59 for(int i = 1; i <= res; i++) tot += node[i].cnt; 60 printf("%d ", n-tot); 61 } 62 } 63 return 0; 64 }