题目背景
任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。
题目描述
任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。
输入输出格式
输入格式:
输入:待拆分的自然数n。
输出格式:
输出:若干数的加法式子。
输入输出样例
输入样例#1:
7
输出样例#1:
1+1+1+1+1+1+11+1+1+1+1+21+1+1+1+31+1+1+2+21+1+1+41+1+2+31+1+51+2+2+21+2+41+3+31+62+2+32+53+4
说明
用回溯做。。。。
n\le 8n≤8
dfs
(按照划分的数的个数来划分)
#include#include #include #include using namespace std;int n,sum,num[50];int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}void dfs(int x,int k,int s,int w){ //num[++sum]=x; if(k==0) { if(w!=n) return; for(int i=1;i 1;i--) dfs(1,i,n,1); return 0; }
搜索,由于1 1 5 跟5 1 1 为一种划分方式,这样相同的划分方式只要后面的数比前面的数小的一定已经被划分过一次了。那么我们进行划分的时候枚举每一个数,枚举的数保证后面的数一定比前面的数大。
#include#include #include #include using namespace std;int n,sum,num[50];int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}void dfs(int s,int k){ for(int i=num[k-1];i<=n;i++) { if(s>=i) { s=s-i; num[k]=i; if(s==0) { if(k==1) continue; for(int j=1;j