问题描述 有M个小孩到公园玩,门票是1元。其中N个小孩带的钱为1元,K个小孩带的钱为2元。售票员没有零钱,问 这些小孩共有多少种排队方法,使得售票员总能找得开零钱。注意:两个拿一元零钱的小孩,他们的位置 互换,也算是一种新的排法。(M<=10) 输入 输入一行,M,N,K(其中M=N+K,M<=10). 输出 输出一行,总的排队方案。 输入样例 4 2 2 输出样例 8 /*********************************************** 题目可能不是很难,和排列组合有关,我的数学不是 很好但这题能想到解法,不过却想了很久不知道怎么 表达这个解法,开始用想用普通数组通过递归求解。 没解决,最后终于想到了二叉树,呵呵,总算解决了 不过遗憾,开始没考虑特殊数据 1 1 0 ,WA了一次 题目 M<=10,以下程序不受此限制。 --- 2007--6--5 --- ***********************************************/ #include <stdio.h>#include <malloc.h> typedef struct tree{ int i,dibs; struct tree *left,*right,*parent;}TREE; TREE* GetTreeNode(void){ TREE *temp; temp = (TREE*)malloc(sizeof(TREE)); temp->dibs = temp->i = 0; temp->left = temp->right = temp->parent = NULL; return temp;} void CreateTree(int n, int k, TREE **p){ TREE *temp; if(n==0 && k==0) return ; if(n >= 1){ temp = GetTreeNode(); temp->dibs = ((*p)->dibs)+1; temp->i = n; temp->parent = *p; (*p)->left = temp; CreateTree(n-1,k,&temp); } if(k >= 1 && (*p)->dibs >= 1){ temp = GetTreeNode(); temp->dibs = ((*p)->dibs)-1; temp->i = k; temp->parent = *p; (*p)->right = temp; CreateTree(n,k-1,&temp); }} int main(){ int m,n,k,sum,t,flag; TREE *head,*temp; scanf("%d%d%d",&m, &n, &k); head = GetTreeNode(); head->dibs = 1; head->i = n; CreateTree(n-1, k, &head); if(m == 1 && n==1){ printf("1\n"); return 0; } for(sum=0, flag=t=1; head->parent!=NULL||head->left||head->right;){ head->i = t * head->i; t = head->i; if(head->left){ flag++; temp = head->left; head->left = NULL; head = temp; } else if(head->right){ flag++; temp = head->right; head->right = NULL; head = temp; } else { temp = head; head = head->parent; free(temp); if(flag == m) sum += t; t = 1; flag--; } } printf("%d\n",sum); return 0;}

评论