GOJ 1146

[栈]http://222.200.98.145:8000/JudgeOnline/showproblem?problem_id=1146

  这题解法不多,我只想到递归式解法.这道题想出解法不难,但如果对栈没有很好地理解实现起来是很棘手的.递归的解法最容易想了,但这里字符串长度可达350000, 递归很容易TLE, 曾写过一个递归的,TLE了. 只能用递归的思想->栈来写,也就是说用栈模拟递归.

  解法思路: 从字符串左往右遍历, 遇到'(' , 放进栈里, 栈size加1.遇到')'时,开始处理.前面必有一个'('与之对应,则这对'()'里的总面积就可以求出来了,处理过程要不停保存当前'()'的长度和高度. 外面一层'()'面积等于里面那层的(长度+1)*(高度+1).这是主要的递推式.处理好这一环,这题就迎刃而解了.在提交的时候出现一点奇怪的事,当数据以"lld"格式输出时oj判错,当数据以"I64d"输出时,AC!!..oj的编译器标明是g++,却对__64int支持得那么好而不是long long..不解.

代码
1 #include < iostream >
2 #include < cstdio >
3 #include < cstring >
4   using namespace std;
5
6 const int MAXN = 350010 ;
7 long long len[MAXN], high[MAXN];
8
9 long long Max( long long a, long long b)
10 {
11 return a < b ? b:a;
12 }
13 int main()
14 {
15 int T;
16 char str[MAXN];
17 long long stack, ans;
18 scanf( " %d " , & T);
19 while ( T -- )
20 {
21 ans = stack = 0 ;
22 scanf( " %s " , str);
23 for ( int i = 0 ; str[i] != ' \0 ' ; ++ i )
24 {
25 if ( str[i] == ' ( ' )
26 {
27 stack ++ ;
28 }
29 else
30 {
31 ans += (high[stack + 1 ] + 1 ) * (len[stack + 1 ] + 1 ) * (stack % 2 == 0 ?- 1 : 1 );
32 high[stack] = Max(high[stack + 1 ] + 1 , high[stack] );
33 len[stack] += len[stack + 1 ] + 2 ;
34 high[stack + 1 ] = len[stack + 1 ] = 0 ;
35 if ( stack == 1 )
36 high[ 1 ] = len[ 1 ] = 0 ;
37 stack -- ;
38 }
39 }
40 printf( " %lld\n " , ans);
41 }
42 return 0 ;
43 }
44

你可能感兴趣的:(Go)