将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,…。编程求出正整数N的所有整数分解式子。

输入格式:

每个输入包含一个测试用例,即正整数N (0

输出格式:

按递增顺序输出N的所有整数分解式子。递增顺序是指:对于两个分解序列N_1={_n_1,_n_2,⋯}和_N_2={_m_1,_m_2,⋯},若存在_i使得n_1=_m_1,⋯,_n__i=m__i,但是n__i+1<_m__i_+1,则_N_1序列必定在_N_2序列之前输出。每个式子由小到大相加,式子间用分号隔开,且每输出4个式子后换行。

输入样例:

  1. 7

输出样例:

  1. 7=1+1+1+1+1+1+1;7=1+1+1+1+1+2;7=1+1+1+1+3;7=1+1+1+2+2
  2. 7=1+1+1+4;7=1+1+2+3;7=1+1+5;7=1+2+2+2
  3. 7=1+2+4;7=1+3+3;7=1+6;7=2+2+3
  4. 7=2+5;7=3+4;7=7
  1. 其实用数字直接表示这个结果看起来就很直观了
  2. 1 1 1 1 1 1 1
  3. 1 1 1 1 1 2
  4. 1 1 1 1 3
  5. 1 1 1 2 2
  6. 1 1 1 4
  7. 1 1 2 3
  8. 1 1 5
  9. 1 2 2 2
  10. 1 2 4
  11. 1 3 3
  12. 1 6
  13. 2 2 3
  14. 2 5
  15. 3 4
  16. 7
  1. //一直没思路 看百度ing
  2. #include<stdio.h>
  3. //深度优先DFS 遍历
  4. //启发很大 https://www.cnblogs.com/andywenzhi/p/5738715.html
  5. //好家伙 算是默写下来了
  6. int n;
  7. int s[31];
  8. int top = -1;
  9. int cnt = 0;
  10. int sum = 0;
  11. void dfs(int i);
  12. int main()
  13. {
  14. scanf("%d", &n);
  15. dfs(1);
  16. return 0;
  17. }
  18. void dfs(int i){
  19. if(sum==n)
  20. {
  21. cnt++;
  22. printf("%d=", n);
  23. for(int k=0; k<top; k++)
  24. printf("%d+", s[k]);
  25. if(cnt%4==0 || s[top]==n)//如果漏掉s[top]==n的话无法通过
  26. printf("%d\n", s[top]);//输出表达式最末尾的栈顶
  27. else
  28. printf("%d;", s[top]);
  29. return;
  30. }
  31. if(sum>n)
  32. {
  33. return;
  34. }
  35. for(int j=i; j<=n; j++)//只有sum<n时运行 j=i?
  36. {
  37. s[++top] = j;
  38. sum += j;
  39. dfs(j);//这里改为dfs(i)会怎样?
  40. sum -= j;
  41. top--;
  42. }
  43. }
  1. 本质上其实不难 但是为什么我理解不了
  2. 手算推一下
  3. 第一轮
  4. 1111111111111211111131111114111111511111161111117 输出(1(1(1(1(1(1(1
  5. 第二轮
  6. 11111211111311111411115111116111117 输出(1(1(1(1(1(2
  7. 第三轮
  8. 11113 输出(1(1(1(1(3
  9. 第四轮
  10. 11122
  11. 以此类推
  12. 等以后完善