HHUOJ 1321

1321: 恶搞指数

时间限制: 1 Sec  内存限制: 32 MB
提交: 129  解决: 61
[提交][状态][讨论版][命题人:外部导入]

题目描述

小明的朋友过生日,小明准备了一件礼物,不过小明想恶搞一下他的朋友,所以他准备了一堆盒子,其中有一个盒子里面装了礼物。盒子里面可以再放零个或者多个盒子。假设放礼物的盒子里不再放其他盒子。
用()表示一个盒子,B表示礼物,小明想让你帮他算出恶搞指数,即最少需要拆多少个盒子才能拿到礼物。

输入

输入包含多组测试数据。每组测试数据是一个长度不大于1000,只包含(,)和 B 三种字符的字符串,代表小明设计的礼物透视图。
题目保证每个透视图都是合法的。

输出

对于每组测试,请在一行里面输出恶搞指数。

样例输入

((((B)()))())
(B)

样例输出4

1



括号嵌套的扩展题。
经历了多次优化,终于把内存压榨到最小。



思路一:利用STL栈。
调用封装好的STL非常舒服,但内存用量排名垫底。
 1 #include <iostream>
 2 #include <stack>
 3 #include <string>
 4 using namespace std;
 5 int main(void)
 6 {
 7     string exp;
 8     while (cin >> exp)
 9     {
10         stack<char> S;
11         for (int i = 0; i < exp.size(); ++i)
12         {
13             if (exp[i] == 'B')
14                 break;
15             else
16             {
17                 switch (exp[i]) {
18                 case '(':
19                     S.push(exp[i]);
20                     break;
21                 case ')':
22                     S.pop();
23                     break;
24                 }
25             }
26         }
27         printf("%d\n", S.size());
28     }
29     return 0;
30 }

 

思路一优化:手写链表模拟栈

本以为会比现成的STL好一点,但貌似还不如STL(境界太低)。可能异常处理占了一部分内存。

代码取自数据结构应用 - 栈,真的从头实现的话太不划算了。

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 struct Node
 5 {
 6     int value;
 7     Node *next;
 8 };
 9 
10 //创建了一个头节点为S的链栈,S将一直表示栈顶元素
11 Node *CreatStack()
12 {
13     Node *S = new Node;
14     S->next = NULL;
15     return S;
16 }
17 
18 int IsEmpty(Node *S)
19 {
20         return S->next == NULL;
21 }
22 void Pop(Node *S)
23 {
24     Node *FirstCell;
25     if(IsEmpty(S))//空栈,将返回异常
26         cout << "Empty Stack" << endl;
27     else
28     {
29         FirstCell = S->next;//取出栈顶
30         S->next = S->next->next;//使S指向新的栈顶
31         delete FirstCell;//删除原栈顶,完成出栈
32     }
33 }
34 void Push(int x, Node *S)
35 {
36     Node *TempCell = new Node;
37     if (TempCell == NULL)
38         cout << "Out of space" << endl;
39     else
40     {
41         TempCell->value = x;//把x赋值给value
42         TempCell->next = S->next;//将新节点设为栈顶
43         S->next = TempCell;//使S指向新的栈顶
44     }
45 }
46 int Print(Node *S)
47 {
48     int cnt = 0;
49     Node *p = S->next;//将p初始化为栈顶
50     while (p != NULL)
51     {
52         cnt++;
53         p = p->next;
54     }
55     return cnt;
56 }
57 
58 int main(void)
59 {
60     string exp;
61     while (cin >> exp)
62     {
63         Node *S = CreatStack();
64         for (int i = 0; i < exp.size(); ++i)
65         {
66             if (exp[i] == 'B')
67                 break;
68             else
69             {
70                 switch (exp[i]) {
71                 case '(':
72                     Push(exp[i],S);
73                     break;
74                 case ')':
75                     Pop(S);
76                     break;
77                 }
78             }
79         }
80         printf("%d\n", Print(S));
81     }
82     return 0;
83 }

 

思路二:重新思考。

想不通前面的人怎么能把内存压缩到那么小,肯定是算法本身不够优(甩锅给STL失败...)

前面的思路基本是基于括号嵌套这一母题来做的,借鉴的是栈混洗。

而这道题与母题不同的是,这次给出的表达式一定是括号匹配的,而且多出了一个礼物B。这不就是天然的二分法吗...

前面的思路中,要拆开的层数就是最后留在栈中的左括号的数量,但其实仔细观察,B前面的左括号数和B后面的右括号数应该是一样多的

实现如下:

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5 int main()
 6 {
 7     string s;
 8     int num, i;
 9     while (cin>>s)
10     {
11         num = 0;
12         for (i = 0; i < s.size(); i++)
13         {
14             if (s[i] == 'B')break;
15             else if (s[i] == '(')num++;
16             else num--;
17         }
18         printf("%d\n", num);
19     }
20     return 0;
21 }

 

思路二优化:string及cin优化

对于dalao来说根本不存在这一步优化。

但实际上思路二实现后与思路一相比进步还不够。

完全抛弃C++改用纯C后能进一步优化。

 1 #include <stdio.h>
 2 #include <string.h>
 3 int main()
 4 {
 5     char exp[1000];
 6     while (scanf_s("%s",exp) != EOF)
 7     {
 8         int num = 0;
 9         int i;
10         for (i = 0; i < strlen(exp); i++)
11         {
12             if (exp[i] == 'B')break;
13             else if (exp[i] == '(')num++;
14             else num--;
15         }
16         printf("%d\n", num);
17     }
18     return 0;
19 }

这样应该是把C的效率压榨到头了。

 

题是水题,但还是有一点启发的,那就是,我再也不要手写STL了(逃

转载于:https://www.cnblogs.com/CofJus/p/10411609.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值