• 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
    ", 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
    ", 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
    ", 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
    ", num);
    17     }
    18     return 0;
    19 }

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

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

  • 相关阅读:
    Javascript事件模型
    关于node.js(一)
    JavaScript表单编程总结
    使用Dom操纵样式表
    文档对象模型Dom
    浏览器对象模型BOM总结
    在javascript中正则表达式的概念与应用
    CSS块级元素、内联元素概念
    HTTP协议
    [学习记录]BFS思路详解
  • 原文地址:https://www.cnblogs.com/CofJus/p/10411609.html
Copyright © 2020-2023  润新知