题解 P3056 【[USACO12NOV]笨牛Clumsy Cows】

ljc20020730

2019-08-06 21:20:54

Solution

好久没刷水题了,水一篇博客。 看到题解区那么鱼龙混杂的题解,我还是先抛砖引玉,讲一个最简单的也最容易理解的题解吧。 首先,我们贪心的想将足够多的()括号匹配掉。这可可以使用栈来实现,如何当前元素为(那么直接插入栈,如果为)那么如果栈顶元素为(那么弹栈找到一组合法匹配,否则插入栈顶。 最终栈中元素必然是$cnt1$个`(`和$cnt2$个`)`组成的,所以将两个(部分和)部分分开考虑,在每一个相同符号的区域内,先间隔地把符号取反,然后最终可能会剩余一个`)(`然后再加`2`即可。 综上所述,如果$cnt_1 $和$cnt_2$的都是偶数直接输出$(cnt_1 + cnt_2)/2$否则输出$(cnt_1 + cnt_2)/2 + 2$ 你懂了么。 ```cpp # include<bits/stdc++.h> using namespace std; stack<char>t; char s[100010]; int main() { scanf("%s",s+1); int len=strlen(s+1); for (int i=1;i<=len;i++) { if (s[i]=='(') t.push('('); else { if (t.size()&&t.top()=='(') t.pop(); else t.push(')'); } } int cnt1=0,cnt2=0; while (t.size()) { if (t.top()==')') cnt1++; else cnt2++; t.pop(); } if (cnt1%2==0&&cnt2%2==0) printf("%d\n",(cnt1>>1)+(cnt2>>1)); else printf("%d\n",(cnt1>>1)+(cnt2>>1)+2); return 0; } ```