两道递归算法题

第一题: 给出{1, 2, 3,…, n}的入栈顺序, 输出所有可能的出栈顺序

#include "stdafx.h"
#include <stack>
#include <queue>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int n = 0;
typedef stack<int> Stack;
typedef queue<int> Queue;

void dfs(int level,Stack s, Queue buf, const int LEVEL);

/*
 * 每一次递归都只有一个元素(level)入栈, 但是可能有0个元素出栈, 也可能有至少一个元素出栈
 * @param level 当前规模            the scale of current sub-problem
 * @param s     当前子问题的栈       the stack of current sub-problem
 * @param buf   当前子问题的打印队列  the printing queue of current sub-problem
 * @param LEVEL 最大规模             the maximum scale of the problem
 */
void dfs(int level,Stack s, Queue buf, const int LEVEL)
{
    // By using "#pragma region xxx" direction, the code can appear more gracefully~
#pragma region Termination of recursion
    if (level == LEVEL)
    {
        // first we print all elements in the queue
        buf.push(level);
        while(!buf.empty())
        {
            cout<<buf.front()<<" ";
            buf.pop();
        }
        // then we clear the stack
        while(!s.empty())
        {
            cout << s.top()<<" ";
            s.pop();
        }
        cout<<endl;
        n++;
        return;
    }
#pragma endregion 当level==LEVEL的时候递归停止

    Queue tempQueue(buf);
    s.push(level);

    Stack tempStack(s);
    /*
     * 非常重要的步骤
     * 把当前问题分解成若干子问题
     * 必须考虑到所有可能的子问题, 如
     * 1. push then no pop
     * 2. push then pop 1
     * 3. push then pop 2
     *    ......
     */
    while(!s.empty())
    {
        buf.push(s.top());
        s.pop();
        dfs(level+1, s, buf, LEVEL);
    }
    dfs(level+1, tempStack, tempQueue, LEVEL);
}

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned int cases;
    int x;

    scanf("%d", &cases);
    while(cases--)
    {
        Stack s = Stack();
        Queue q = Queue();
        cin>>x;
        dfs(1, s, q, x);
        cout<<"the catalan number of "<<x<<" is "<<n<<endl;
        n=0;
    }
    system("shutdown -s -t 60");
}

二.

Input a positive integer n(n>=3),write a function to print all the possibilities of combination of 1,1,2,2,3,3,......,n,n( 2n numbers altogether) that satisfies:
    there is 1 integer between two “1”s
    there are 2 integers between two “2”s
    there are 3 integers between two “3”s
    ......
    there are n integers between two “n”s
    for example of 3,the two possible sequence are:231213 or 312132.
    Pay attention, there may be 0 or many possible sequences, print them all

结果类Result.h

#pragma once;
class Result
{
private:
    int* data;
    int n;
public:
    Result(int _N):n(_N)
    {
        data = new int[2*n];
        recover();
    }

    ~Result() {delete[] data;}

    Result(const Result& src)
    {
        n = src.n;
        data = new int[2*n];
        for(int i=0; i<2*n; ++i)
        {
            data[i] = src[i];
        }
    }

    int& operator[](int index)
    {
        return data[index];
    }

    const int& operator[] (int index) const
    {
        return data[index];
    }

    bool insert(int i, int level)
    {
        if (i<0 || i+level+1>2*n) return false;
        if (data[i]==0 && data[i+level+1]==0)
        {
            data[i] = data[i+level+1] = level;
            return true;
        }
        else return false;
    }

    void recover()
    {
        for (int i=0; i<2*n; ++i)
        {
            data[i] = 0;
        }
    }

    Result& operator=(const Result& src)
    {
        delete[] data;
        n = src.n;
        data = new int[2*n];
        for(int i=0; i<2*n; ++i)
        {
            data[i] = src[i];
        }
        return *this;
    }

    int size() const
    {
        return 2*n;
    }

    void print() const
    {
        for(int i=0; i<2*n; ++i)
            printf_s("%d ", data[i]);
        printf_s("\n");
    }
};

核心算法:

#include "stdafx.h"
#include "Result.h"
#include <stack>
#include <queue>
#include <list>
#include <vector>
using namespace std;

void dfs(int level, Result res)
{
    if (level<1)
    {
        res.print();
        return;
    }

    Result temp = res;
    for (int i=0; i<res.size()-level-1; ++i)
    {
        if (temp.insert(i, level))
        {
            dfs(level-1, temp);
            temp = res;
        }
        else continue;
    }
}

int _tmain(int argc, _TCHAR* argv)
{
    int cases;
    scanf_s("%d", &cases);
    while (cases--)
    {
        int n;
        scanf_s("%d", &n);
        Result res = Result(n);
        dfs(n, res);
    }
}
时间: 2024-10-15 09:31:50

两道递归算法题的相关文章

逛园子,看到个练习题,小试了一把(淘宝ued的两道小题)

闲来无事,逛园子,充充电.发现了一个挺有意思的博文,自己玩了一把. 第一题:使用 HTML+CSS 实现如图布局,border-widht 1px,一个格子大小是 60*60,hover时候边框变为橘红色(兼容IE6+,考虑语义化的结构) 效果图: 简单分析一下: 使用伪类 :hover的时候相对定位 改变z-index, 代码如下: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta c

数论——异或,两道水题。

第一题:(没有链接) 题目大意:给你n个数(n <= 1000000),第i个数用ai表示(每个a <= 1000000),求出每个数与其之后的数的xor和. 举个例子吧,比如三个数1 2 3答案就应该为1 xor 2 + 1 xor 3 + 2 xor 3 = 4; 题解: 首先有一个O(n*n)的算法,就是暴力枚举,可以过40%数据. 程序大体: for (int i = 1;i < n;i ++) for (int j = i + 1;j <= n;j ++) ans +=

两道水题

昨天同桌为我推荐了p1904这道水题,然后他就写不出来了--本来不想写,但是看他写得很麻烦,为了给他展示我的代码能力就写了一下. 即使类型为"其他",但还是掩盖不了模拟的事实.那么直接sort Ai,再在前k个牛中找到Bi最高的就行.复杂度为N*logN+k #include<iostream> #include<iomanip> #include<cstdio> #include<algorithm> using namespace s

两道递推公式题的解题报告

T1(阿牛的EOF牛肉串) 题意:一串由EOF三个字母组成的长度为\(n\)的字母串,不能出现连续的OO,求字符串种类数\(f[n]\) 答案:\(f[n]=2f[n-1]+2f[n-2]\) --① 注解: 如果a[n]取E,该情况下种类为f[n-1]: 如果a[n]取F,该情况下种类为f[n-1]; 如果a[n]取O,则只能取a[n-1]为E或F,分别有f[n-2]种. 综上,一共有f[n-1]+f[n-1]+f[n-2]+f[n-2]种. T2 (原题找不到了,恳请见过的巨佬提供线索) 题

两道趣题

好吧,估计以后会觉得这两道题很沙雕,但我现在实在太菜了-- pro.1 给定\(n\),求$ \sum\limits_{i = 1}^n {\left[ {\frac{n}{i}} \right]} $,数据范围\(1 \leqslant n \leqslant 10^{12}\). 首先\(O(n)\)肯定凉了,所以得找规律(又是找规律,害怕.jpg 根据 看std 手模与观察,可以发现在一段区间内的值是相等的,最明显的就是在\(\left[ {\frac{n}{{n/2}}} \right]

高数吧两道证明题

1.设$y=f(x),x\in (-\infty,+\infty)$的图形关于$y=a,y=b$均对称$(a< b),$求证:$y=f(x)$是周期并求其周期. 证:由题可得:$$f(a-x)=f(a+x)$$ 令$$x=a+x,$$ 得$$f(2a+x)=f(x).$$ 同理可得:$$f(2b+x)=f(x)$$ 所以$$f(2b+x)=f(2a+x)$$ 令$$x=x-2a,$$ 所以$$f(x)=f(x+2b-2a)$$ 所以$f(x)$是周期函数,周期$T=2(b-a).$ 注:无特殊说

关于有序二维矩阵查找和字符串替换的两道算法题

最近看一本书上写到的两个面试题 于是实现了一下 感觉思路很好,大牛略过 : 1.对于一个二维矩阵,从左到右  从上到下 都是递增的,如何判断一个值是否在矩阵内部?(C实现  实现复杂度 O(n)) bool FindInTwoDimensionalMatrix(int*pMatrix,int iRows,int iCols,int iFindVal) { bool bFind=false ; if(pMatrix==0||iRows<=0||iCols<=0) return bFind ; i

Java基础知识强化11:多态的两道基础题

1.第1题 1 class Base { 2 public void method() { 3 System.out.print("Base method"); 4 } 5 } 6 7 class Child extends Base { 8 public void methodB() { 9 System.out.print("Child methodB"); 10 } 11 } 12 13 class Sample { 14 public static void

Co-prime Array&amp;&amp;Seating On Bus(两道水题)

Co-prime Array Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 660A Description You are given an array of n elements, you must make it a co-prime array in as few moves as possible. In ea