递归与递推学习笔记

递归与递推

93. 递归实现组合型枚举

从 1~n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案。

输入格式:

两个整数 n,m 在同一行用空格隔开。

输出格式

按照从小到大的顺序输出所有方案,每行1个。

首先,同一行内的数升序排列,相邻两个数用一个空格隔开。

其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7 排在 1 3 6 8 前面)。

数据范围:

n > 0 ,

0 ≤ m ≤ n ,

n + ( n − m ) ≤ 25

输入样例

5 3

输出样例:

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 

代码

#include<iostream>

using namespace std;
int m, n;

void dfs(int t, int u, int state) {
    if (u + n < m + t)return;//判断剩下的还够不够选
    if (u == m) {//选够 m 个数了便输出
        for (int i = 0; i < n; i++) {
            if (state >> i & 1)
                cout << i + 1 << " ";
        }
        cout << endl;
        return;
    }
    dfs(t + 1, u + 1, state | 1 << t);//搜索选第 t 个数的情况
    dfs(t + 1, u, state);//搜索不选第 t 个数的情况
}

int main() {
    cin >> n >> m;
    dfs(0, 0, 0);
    return 0;
}
92. 递归实现指数型枚举

从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。

输入格式:

输入一个整数n。

输出格式:

每行输出一种方案。

同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。

对于没有选任何数的方案,输出空行。各行(不同方案)之间的顺序任意。

数据范围:

1 ≤ n ≤ 15

输入样例:

3

输出样例:

3
2
2 3
1
1 3
1 2
1 2 3

代码:

#include <iostream>

using namespace std;
bool ge[100001] = {false};
int n;

void dfs(int t) {
    if (t > n) {
        for (int i = 1; i <= n; ++i)
            if (ge[i])
                cout << i << " ";
        cout << endl;
        return;
    }
    ge[t] = true;
    dfs(t + 1);
    ge[t] = false;
    dfs(t + 1);
}

int main() {
    cin >> n;
    dfs(1);
    return 0;
}
95.费解的开关

你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

10111
01101
10111
10000
11011

在改变了最左上角的灯的状态后将变成:

01111
11101
10111
10000
11011

再改变它正中间的灯后状态将变成:

01111
11001
11001
10100
11011

给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。

输入格式:

第一行输入正整数 n,代表数据中共有 n 个待解决的游戏初始状态。

以下若干行数据分为 n 组,每组数据有 5 行,每行 5 个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。

输出格式:

一共输出 n 行数据,每行有一个小于等于 6 的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。

对于某一个游戏初始状态,若6步以内无法使所有灯变亮,则输出“-1”。

数据范围:

0<n≤500

输入样例:

3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111

输出样例:

3
2
-1

思路:
遍历第一行所有情况,然后以递推的方式按行判断开灯方式

代码:

#include <iostream>
#include <cstring>

using namespace std;
const int INF = 1000000;
char g[10][10];
int dx[5] = {0, -1, 0, 1, 0};
int dy[5] = {0, 0, 1, 0, -1};

void turn(int x, int y) {
    for (int i = 0; i < 5; ++i) {
        int a = x + dx[i], b = y + dy[i];
        if (a >= 0 && a < 5 && b >= 0 && b < 5)
            g[a][b] ^= 1;
    }
}

int work() {
    int ans = INF;
    for (int i = 0; i < 1 << 5; ++i) {
        int res = 0;
        char backup[10][10];
        memcpy(backup, g, sizeof g);
        for (int j = 0; j < 5; ++j) {
            if (i >> j & 1) {
                res++;
                turn(0, j);
            }
        }
        for (int j = 0; j < 4; ++j) {
            for (int k = 0; k < 5; ++k) {
                if (g[j][k] == '0') {
                    res++;
                    turn(j + 1, k);
                }
            }
        }
        bool isSucc = true;
        for (int j = 0; j < 5; ++j) {
            if (g[4][j] == '0') {
                isSucc = false;
                break;
            }
        }
        if (isSucc)ans = min(ans, res);
        memcpy(g, backup, sizeof g);
    }
    if (ans > 6)return -1;
    return ans;
}

int main() {
    int n;
    cin >> n;
    while (n--) {
        for (int i = 0; i < 5; ++i)
            cin >> g[i];
        cout << work() << endl;
    }
    return 0;
}
posted @   嘿,抬头!  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示