第5章-递归及应用(2020.04.09)

第5章-递归及应用

1. 二进制转换为十进制【中等】

请用递归的方式实现二进制向十进制转换。
【输入】 二进制序列,长度小于20
【输出】 二进制对应的10进制数
例如:
【输入】111001
【输出】57

#include <iostream>
#define maxlen 21
using namespace std;

long two_to_ten(char *s, long sum)
{
    if (*s == '\0') 
        return sum;
    else {
        sum = sum * 2 + (*s - '0');
        two_to_ten(s + 1, sum);
    }
}

int main()
{
    char s[maxlen] = {'\0'};
    cin >> s;
    cout << two_to_ten(s, 0);
    return 0; 
}
2. Letter Combinations of a Phone Number【中等】

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
2->abc
3->def
4->ghi
5->jkl
6->mno
7->pqrs
8->tuv
9->wxyz
数字对应字母的图片
在这里插入图片描述
【输入】 2-9之间的数字串,长度不超过10,
【输出】 数字串对应的所有字母组合
例如:
【输入】
23
【输出】
ad ae af bd be bf cd ce cf
【输入】
22
【输出】
aa ab ac ba bb bc ca cb cc

#include <iostream>
#include <vector>
using namespace std;

void Combination(string digits, int level, vector<string>& results, string dict[], string curr) {
    if (level == digits.size()) {
        results.push_back(curr);
        return;
    }
    int index = digits[level] - '0';
    string tmp = dict[index];
    for (int i = 0; i < tmp.size(); i++) {
        string next = curr + tmp[i];
        Combination(digits, level + 1, results, dict, next);
    }
}

vector<string> letterCombinations(string digits) {
    vector<string> results;
    if (digits.size() <= 0) return results;
    string dict[] = { "", "", "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };
    Combination(digits, 0, results, dict, "");
    return results;
}

int main()
{
    string a;
    cin >> a;
    vector<string> b = letterCombinations(a);
    int len = b.size();
    for (int i=0; i < len; i++) {
        cout << b[i] << ' ';
    }
    return 0;
}
3. n个数的全排列【中等】

给定整数n,n<=10,请求出n的全排列。
N=3时,1-3的排列可以为:
1:1 2 3
2:1 3 2
3:2 1 3
4:2 3 1
5:3 1 2
6:3 2 1
一共有6种情况
【输入】 整数n,n<=20
【输出】
1-n的排列 (排列数大于10的,仅输出前10组即可)
总的全排列数
例如:
【输入】 4
【输出】
1:1 2 3 4
2:1 2 4 3
3:1 3 2 4
4:1 3 4 2
5:1 4 2 3
6:1 4 3 2
7:2 1 3 4
8:2 1 4 3
9:2 3 1 4
10:2 3 4 1
24

#include <iostream>
using namespace std;

int n, cnt = 1;
long long sum = 1;
int arr[21] = { 0 };//保存每次输出的数组
int record[21] = { 0 };//记录一个数是否在数组里

void quanpailie(int num)
{
    if (cnt > 10) {
        return;
    }
    if (num == n + 1) {
        cout << cnt << ':';
        for (int i = 1; i <= n; i++) {
            cout << arr[i] << ' ';
        }
        cout << endl;
        cnt++;
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (record[i] == 0) {//如果i没有在数组里面
            arr[num] = i;//填上i
            record[i] = 1;//i已经进入数组
            quanpailie(num + 1);//填下一个位置
            arr[num] = 0;
            record[i] = 0;//把i收回,试下面一个数
        }
    }
    return;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) {
        sum *= i;
    }
    quanpailie(1);
    cout << sum;
    return 0;
}
4. A Maze Problem【中等】

A maze is to be represented by a 12*12 array composed of three values: Open, Wall, or Exit. There is one exit from the maze. Write a program to determine whether it is possible to exit the maze from the starting point (any open square can be a starting point). You may move vertically and horizontally to any adjacent open square(左右上下四个方向). You may not move to a square containing a wall. The input consists of a series of 12 lines of 12 characters each, representing the contents of each square in the maze. The characters are O, W, or E.
【输入】 12×12的迷宫方阵,每个格子的可能取值有:O, W, or E,输入数据能够确保迷宫只有一个出口。
任意3个起点的坐标,格式如下(x,y)。其中x为纵坐标,y为横坐标,起始坐标从左上角的格子开始,坐标起始值为0.
【输出】
起点到出口的最短路径长度(经过多少个方格),若起点无法到达出口则输出-1。起始节点和结束节点都算入路径长度的计算。

例如:
【输入】
O W O W O W O O W O W O
O W O W W W W O W O O E
O W W W O O O O O O O O
W W W O O O O W W W O W
O O O O W W W O O O O O
O O W O W O W O W O W W
O W W O O O W W O O O W
O O W O O W W W O O O O
O O O W O O O O W W W W
W W W O O O O W W W O O
O W W W W O O O O O W W
W W W O O O O O W W W W
(0,0) (5,7) (7,8)
【输出】
-1 9 10
【解释】
输出表示第一个点(0,0)无法到达出口;
第二个点(5,7)到达出口的最短路径是9;
第三个点(7,8)到达出口的最短路径是10。

注:

  1. 这道题输入的时候字母中间没有空格。
  2. 我采用的加墙方法被助教一顿吐槽,建议用下标判断是否越界。
#include <iostream>
#include <cstdio>
const int max_maze = 12;
using namespace std;

class Maze
{
public:
    Maze();
    void creat_maze(int max_maze);
    void creat_judge();
    int get_flag();
    int get_step();
    void dfs(int x, int y, int step);
private:
    int min, flag;
    char MAZE[max_maze + 2][max_maze + 2];
    int judge[max_maze + 2][max_maze + 2];
};

Maze::Maze()
{
    
}

void Maze::creat_maze(int max_maze)
{
    int i, j;
    char a;
    //加墙
    for (i = 0; i < max_maze + 2; i++) {
        MAZE[0][i] = 'W';
        MAZE[max_maze + 2][i] = 'W';
        MAZE[i][0] = 'W';
        MAZE[i][max_maze + 2] = 'W';
    }
    //输入
    for (i = 1; i <= max_maze; i++) {
        for (j = 1; j <= max_maze; j++) {
            cin >> a;
            MAZE[i][j] = a;
        }
    }
}

void Maze::creat_judge()
{
    flag = 0;
    min = max_maze * max_maze;
    int i, j;
    for (i = 1; i <= max_maze; i++) {
        for (j = 1; j <= max_maze; j++)
            judge[i][j] = 0;
    }
}

int Maze::get_flag()
{
    return flag;
}

int Maze::get_step()
{
    return min;
}

void Maze::dfs(int x, int y, int step)
{
    //终点时
    if (MAZE[x][y] == 'E') {
        if (step < min) {
            min = step;
            flag = 1;
        }
        return;
    }
    //不是终点时,顺时针试探
    //不要忘了判断E,当走到邻点是E的时候只判断O是进不去递归函数的
    //右
    if ((MAZE[x][y + 1] == 'O' || MAZE[x][y + 1] == 'E') && judge[x][y + 1] == 0) {
        //可以向右时,设置为已访问
        judge[x][y + 1] = 1;
        dfs(x, y + 1, step + 1);
        //回溯时,右边设置为未访问
        judge[x][y + 1] = 0;
    }
    //下
    if ((MAZE[x + 1][y] == 'O' || MAZE[x + 1][y] == 'E') && judge[x + 1][y] == 0) {
        judge[x + 1][y] = 1;
        dfs(x + 1, y, step + 1);
        judge[x + 1][y] = 0;
    }
    //左
    if ((MAZE[x][y - 1] == 'O' || MAZE[x][y - 1] == 'E') && judge[x][y - 1] == 0) {
        judge[x][y - 1] = 1;
        dfs(x, y - 1, step + 1);
        judge[x][y - 1] = 0;
    }
    //上
    if ((MAZE[x - 1][y] == 'O' || MAZE[x - 1][y] == 'E') && judge[x - 1][ y] == 0) {
        judge[x - 1][y] = 1;
        dfs(x - 1, y, step + 1);
        judge[x - 1][y] = 0;
    }
    return;
}

int main()
{
    int x, y;
    Maze a;
    a.creat_maze(max_maze);
    for (int i = 0; i < 3; i++) {
        char c;
        cin >> c >> x >> c >> y >> c;
        a.creat_judge();
        a.dfs(x + 1, y + 1, 1);//因为外面加墙了所以要错开
        if (a.get_flag()) {
            cout << a.get_step() << ' ';
        }
        else cout << -1 << ' ';
        //getchar();
    }
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值