Problem:
同じ大きさの正方形の紙が n 枚ある.これらの紙の下部を水平に揃えて何列かに並べる.ただし,隣り合う列は左側が右側より低くならないように並べなければならない.例えば, n = 5 のときは,次のような 7 通りの並べ方が可能である.

これらを,各列に並んだ正方形の個数の列で表すことにする.例えば, n = 5 の
ときは,それぞれ,

(5) (4, 1) (3, 2) (3, 1, 1) (2, 2, 1) (2, 1, 1, 1) (1, 1, 1, 1, 1)

と表わされる.

n を入力したとき, 辞書式順序で全て出力するプログラムを作成せよ.n ≤30
とする.ただし, 辞書式順序とは2つの並べ方 (a1, a2 , ..., as) が並べ方 (b1, b2, ..., bt ) に対して, a1 > b1 または, ある整数 i > 1 が存在して a1 = b1 , ..., ai-1 = bi-1 かつ ai > bi が成り立つとき (a1, a2, ..., as) が (b1 , b2, ..., bt) より先に出力されるように並べることである.

入力データ は 1 行からなり,1 行目に n が書かれている.

出力には並べ方を辞書式順序で 1 行に1通りずつ書き最後に改行を入れること. 並べ方は (a1, a2, ..., as) の出力は整数 a1, a2, . . . , as をこの順番に空白で区切って出力すること.

入力例１

5

　

出力例１

5

4 1

3 2

3 1 1

2 2 1

2 1 1 1

1 1 1 1 1

入力

入力は複数のデータセットからなる．n が 0 のとき入力が終了する．データセットの数は 5 を超えない．

出力

データセットごとに、辞書式順序で全て出力する．

入力例

5
5
0

出力例

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

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>

typedef struct _linked_arr{
	int arr[31];
	struct _linked_arr *next;
}LINKED_ARR;

LINKED_ARR *makenode(int arr[]);
LINKED_ARR *addnode(LINKED_ARR *p,int arr[]);
void freenode(LINKED_ARR *P);
void makeTREE(LINKED_ARR *P);
void printTREE(LINKED_ARR *P);

int main(){
	
	int sn;
	int a_top[31];
	int i;
	LINKED_ARR *TOP;

	while(scanf("%d\n",&sn)!=EOF){
		if(sn==0)break;

		a_top[0]=sn;
		for(i=1;i<31;i++)a_top[i]=0;
		TOP=makenode(a_top);

		makeTREE(TOP);

		printTREE(TOP);
		
		freenode(TOP);
	}

	return 0;
}


LINKED_ARR *makenode(int arr0[]){

	int i;
	LINKED_ARR *P;
	if((P=(LINKED_ARR *)malloc(sizeof(LINKED_ARR)))==NULL){
		printf("malloc error\n");
		exit(1);
	}
	
	for(i=0;i<31;i++)P->arr[i]=arr0[i];
	P->next=NULL;

	return P;

}

void makeTREE(LINKED_ARR *P){
	
	int i;
	int buf[31];
	int carry;
	LINKED_ARR *Pnext;
	
	
	for(i=0;i<31;i++)buf[i]=P->arr[i];
	if(P->arr[0]==1){
		return;
	}
	carry=0;
	for(i=30;i>=0;i--){
		if(buf[i]==1){
			buf[i]--;
			carry++;
		}else if(buf[i]>1){
			buf[i]--;
			carry++;
			while(carry>0){
				i++;
				while(buf[i-1]>=buf[i]+1&&carry>0){
					buf[i]++;
					carry--;
				}
			}
			break;
		}
	}
//for(i=0;i<31;i++){printf("%d ",buf[i]);} ;puts("\tdebug");

	Pnext=makenode(buf);
	P->next=Pnext;
	makeTREE(Pnext);
	return;

}

void printTREE(LINKED_ARR *P){
	int i;
	for(i=0;i<31;i++){
		if(P->arr[i]){
			printf(P->arr[i+1]==0?"%d\n":"%d ",P->arr[i]);
		}
	}
	if(P->next==NULL){
		return ;
	}
	printTREE(P->next);
	return;
}
void freenode(LINKED_ARR *P){
	if(P->next==NULL){
		free(P);
		return;
	}
	freenode(P->next);
	return;
}