我的发癫题解洛谷P·2404(ps:蒟蒻一只QAQ)

 本题主考搜索与回溯

# 自然数的拆分问题

## 题目描述

任何一个大于 1 的自然数 n,总可以拆分成若干个小于n 的自然数之和。现在给你一个自然数 n,要求你求出 n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

## 输入格式

输入:待拆分的自然数 $n$。

## 输出格式

输出:若干数的加法式子。

## 样例 #1

### 样例输入 #1

```
7
```

### 样例输出 #1

```
1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4
```

## 提示

数据保证,2<=n<=8

#include<bits/stdc++.h>//懒人的万能头,(ps;某教练们建议别用万能头QwQ) 
using namespace std;//我学语文,所以打句号。。。 。。。 。。。 
int n,ji[1000];//ji数组用来存当前的答案,因为我只用一个数组,所以要回溯QAQ。 
//数据是1~8,所以答案最多有8位,即1+1+1+1+1+1+1+1,(n太小了) 。 
void dfs(int sum,int place,int qi){//深搜要什么返回值,void(函数无返回)。 
//说用字典序排,所以sum表示当前答案的总和,即ji数组每一位累加的和 。 
//place表示当前枚举的数是答案的第几位,将当前枚举的数存进ji[place]中,
//qi是记录当前枚举数的大小,because 字典序,所以下一个数要大于等与qi
//即for循环从qi到n-1(为什么n-1???(第一个数一定是1啊QAQ))。 
	if(sum==n){//ji数组中和已经够了,输出?启动!!! 。 
		for(int i=1;i<place-1;i++)//看递归函数(place+1)是只加了1,没存值 
//所以此时 ji数组里只有place个数,但输出有格式,下面说。 
		cout<<ji[i]<<"+";//预处理一下,不输出最后的一个,前面都是数+加号 
		cout<<ji[place-1]<<endl;//单独输出最后一数+我要换行+......(好吧,没了) 
		return ;}//结束了当前的递归,(我是void,我return后不接值,接了报错哦) 
	if(sum>n) return;//sum都大于n了,你还不溜溜溜溜溜溜溜?!结束吧您勒; 
	for(int i=qi;i<=n-1;i++){//作循环,从qi即>=上一个数(理解万岁QAQ!) 
		ji[place]=i;//ji(答案)数组存数+1,准备递归。 
		dfs(sum+i,place+1,i);//递归中sum(总和数组)加枚举的i,下个数存进
//place的下一位,即place+1,下个数从第i个数开始枚举,即qi=i(重复*2) 
		ji[place]=0;//作回溯,重置ji数组,因为:深搜。所以:一条路到底,不会混淆。 
	}//循环结束力。 
}//深搜结束力(悲)。 
int main(){//别告诉我你不会写??!!。 
	cin>>n;//.............................这是输入QAQAQAQAQAQAQAQAQ。 
	dfs(0,1,1);//现在,ji里没值,所以sum=0,习惯从数组1开始存,所以place=1,最小
//加数是1,从1开始作答案,所以qi=1。(句号) 
	return 0;//我结束了,你懂了吗? 
}//咳
//懂的扣1,没懂的扣眼珠子(凶)。 
//下面完整代码。。。。。。。 
/*#include<bits/stdc++.h>
using namespace std;
int n,ji[1000];。 
void dfs(int sum,int place,int qi){  
	if(sum==n){
		for(int i=1;i<place-1;i++)
		cout<<ji[i]<<"+";
		cout<<ji[place-1]<<endl; 
		return ;}
	if(sum>n) return;
	for(int i=qi;i<=n-1;i++){
		ji[place]=i;
		dfs(sum+i,place+1,i);
		ji[place]=0; 
	}
} 
int main(){ 
	cin>>n; 
	dfs(0,1,1);
	return 0;
}*/

虽然2<=n<=8;

但我数组开的1000,你电脑好可以试试n=1000哦 

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值