ACM竞赛学习整理--模拟算法举例POJ1068

什么是模拟

仅仅使用较简单的算法和数据结构的题目。

模拟顾名思义,就是按照题目的要求,一步步写出代码。

常见的模拟方法

a.用数学量和图形描述问题

计算机处理的是数学量。若要用计算机解决实际问题,需要把实际问题抽象为数学量,或者数字。比如,记事本把文字按 ASCII 码表转换为数字储存起 来,极品飞车把赛车的性能表示为数字,来权衡赛车的好坏。
一个漂亮的算法,需要用数学量表示出来。

有时,我们需要用更直观的图形来描述实际问题。

图论就是一个绝佳的方法。图是一种表示离散量间关系的形式,它也是一种思想,常被用于建模。同时,前人也为我们提供了很多现成的图论算法,能够解决很多常 见问题,这些将在之后被提到。

矩阵也是一种常见的方法。有时矩阵被表示成三角形的形式,比如“杨辉三角”。矩阵常常和数学有关,

在计算机计算时常常利用矩阵的递推式。这也将在后面被提 到。

b.模拟计算过程

模拟方法是最常见、最直接的算法构建方法。

在这里插入图片描述

有些模拟算法还涉及到图形和其他复杂的数据结构,这需要我们熟练地运用语言,巧妙地把其他关系转化为数学量间关系。

举例:
POJ1068

Description

Let S = s1 s2…s2n be a well-formed string of parentheses. S can be encoded in two different ways:
q By an integer sequence P = p1 p2…pn where pi is the number of left parentheses before the ith right parenthesis in S (P-sequence).
q By an integer sequence W = w1 w2…wn where for each right parenthesis, say a in S, we associate an integer which is the number of right parentheses counting from the matched left parenthesis of a up to a. (W-sequence).

Following is an example of the above encodings:
S (((()()())))

P-sequence	    4 5 6666

W-sequence	    1 1 1456

Write a program to convert P-sequence of a well-formed string to the W-sequence of the same string.
Input

The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case is an integer n (1 <= n <= 20), and the second line is the P-sequence of a well-formed string. It contains n positive integers, separated with blanks, representing the P-sequence.

Output

The output file consists of exactly t lines corresponding to test cases. For each test case, the output line should contain n integers describing the W-sequence of the string corresponding to its given P-sequence.
Sample Input

2
6
4 5 6 6 6 6
9
4 6 6 6 6 8 9 9 9
Sample Output

1 1 1 4 5 6
1 1 2 4 5 1 1 3 9

问题描述:

一组括号 (((( ) ( ) ( ) ) ) )

有两种描述方法:

P方法:4 5 6 6 6 6 - 每一个)前,有几个(

W方法:1 1 1 4 5 6 - 每一个),向前数几个是跟它匹配的(

要求是根据P求W

解题思路:

1. 虽然没说,但是可以推测出,括号的个数是偶数;第一个一定是(,最后一个一定是)
2. P方法和W方法之间可能存在公式类的规律,但是要寻找不是特别简单
3. 手动分析过程中,我们知道,可以模拟出推到W的过程-模拟法
4. 括号匹配,一定是stack结构
5. 思路就是:根据P还原括号数组,利用stack,推到出W

#include <iostream>
#include <string>
#include <stack>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for (int i=0; i<n; i++)
    {
        int m;
        cin >> m;
        string str;
        int leftpa = 0;
        for (int j=0; j<m; j++)  //使用stack,将p序列还原成括号序列
        {
            int p;
            cin >> p;
            for (int k=0; k<p-leftpa; k++) str += '(';
            str += ')';
            leftpa = p;
        }
        stack<int> s;
        for (string::iterator it=str.begin(); it!=str.end(); it++)
        {//将左括号记为1,压入栈,扫到右括号,弹出栈顶元素,将新的栈顶元素加上已扫到的右括号的数目,
            if (*it=='(')
                s.push(1);
            else
            {
                int p = s.top(); s.pop();
                cout << p << " ";
                if (!s.empty()) s.top() += p;
            }
        }
        cout << endl;
    }
    return 0;
}

PS:

该程序设计当中用到了C++ STL中的stack

C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。

c++ stl栈stack的成员函数介绍:

empty() 堆栈为空则返回真

pop() 移除栈顶元素

push() 在栈顶增加元素

size() 返回栈中元素数目

top() 返回栈顶元素

想必搞懂了堆栈的内容,这样类似的题应该不算难解。

原创文章 41 获赞 0 访问量 2057

猜你喜欢

转载自blog.csdn.net/qq_21291397/article/details/104306767