题解

wc02222 2025-10-02 22:24:14 6

作为wc022的小号(wc0222)的小号(wc02222)

这里先说明: @novice

别搞我小小号,你已经毁了我一个了(wc0222),停手吧!!!QAQ我还要靠这个号发题解提升自己的能力呢(wc022被禁言,wc0222直接封了)

首先给你们看一眼AC代码:

#include <bits/stdc++.h>
using namespace std;
int a[100] = { 0 };
int n, b = 0;
void dfs(int x, int s) {
    int i;
    if (b == n) {
        cout << n << "=" << a[1];
        for (i = 2; i < x; i++) {
            cout << "+" << a[i];
        }
        cout << endl;
        return;
    }
    for (i = s; i < n && i <= n - b; i++) {
        a[x] = i;
        b += i;
        dfs(x + 1, i);
        b -= i;
    }
}
int main() {
    cin >> n;
    dfs(1, 1);
    return 0;
}

虽然是问了豆包,但我不是那种人,这是我叫豆包给我错误代码的基础上改的,并且我还要他将注释加长,好让我看懂(蒟蒻真的想学会深搜和广搜,在csp-j复赛拿个好成绩)

说明:1.初始化全部要放最前面,不然在int mian()后面定义前面的代码会视为没定义就会报错

2.if (b == n)这里是特意多加一个变量,在后面的b += i;的累加中达到结束条件输出当前可行的方案并结束

cout << n << "=" << a[1];
        for (i = 2; i < x; i++) {
            cout << "+" << a[i];
        }
        cout << endl;

3.这个代码如果直接从一开始输出加号和a[i]的话会多一个加号(从二开始会少个一,自己脑补),像这样:

3=+1+1+1

把cout << "+" << a[i];改成cout << a[i]<< "+";并从一开始也不行(从二开始会少个一,自己脑补),会这样:

3=1+1+1+

4.return这个是为了结束当前程序(怕有些初学者不懂)

5.i=s与后面的dfs(x + 1, i);连用,用于记录上一次选的数,使这次选的数不可以小于上个数(保证字典序)

  1. i < n && i <= n - b中,i<n是为了不会出现3=3,7=7这种情况,题目样例中没有,如果有就删去,i<=n-b是判断是否已超出输入的数n

7.dfs(x + 1, i);(很多初学者都不知道这个代码是干嘛的,因为我也是,后来问了豆包才学到)更改变量,使x=x+1,s=i,让s=i见说明五回忆一下使x=x+1是为了让a[x]=i进行一步一步的存数据,避免全存一个数据中(就像你学数组时输入多个数为什么要i++使a[1]变成a[2]再变成a[3]一样,不然全存一个数据就会出错)

8.b -= i;是为了反悔,比如7=1+1+2+2+?(如果在问号添一显然没有保证字典序,也就是数字没从小到大排序,添3又会大,所以这是就会反悔,b-=2(只会减问号上一个数字),就会变成“7=1+1+2+?”这时,只要添3就会出现一个新的方案:“7=1+1+2+3”这个方案就会是对的,就会输出)

9.dfs(1, 1);(这段代码也会有许多初学者不懂,其实就是初始化,将x=1,s=1)

这个题解不经让我对广搜进行了一次巩固,也更希望帮到很多像我这种不太懂广搜的初学者,这个题解我写了很久,很详细,希望大家不是只会复制AC代码,毕竟你抄了却学不懂,都会让你在csp-j以及更高级的比赛中都会少100分总分,我在快开始考今年的csp-j复赛时才意识到(也就是这个帖子发布这天)我已经来不及了,希望你们不会像我一样,到了最关键的时刻,才知道反悔,我估计只能明年了,下次csp-j也是我最后一次了......

{{ vote && vote.total.up }}