數字包牌
抱歉...忘記把這個貼上來((大筆貼忘記了.抱歉
作法:生成組合
第1程式碼:利用遞迴生成組合 ((簡單易懂
第2程式碼:利用陣列生成組合
/***********************************************************/
#include<stdio.h>
#include<stdlib.h>
int way[1001]={0};
int n,m,a,b;
int temp[105]={0};
void make (int now,int a,int n,int m)
{
int b=a,c;
if(now==m+1)
{
for(c=1;c<=m;c++)
printf("%d ",temp[way[c]]);
printf("\n");
return;
}
else
for(b=a;b<=n;b++)
{
way[now]=b;
make(now+1,b+1,n,m);
}
}
main()
{
while(scanf("%d",&n)==1&&n!=0)
{
for(a=1;a<=n;a++)
scanf("%d",&temp[a]);
scanf("%d",&m);
for(a=1;a<=n;a++)
for(b=1;b<=n-1;b++)
if(temp[b]>temp[b+1])
{
int temp1;
temp1=temp[b];
temp[b]=temp[b+1];
temp[b+1]=temp1;
}
make(1,1,n,m);
}
return 0;
}
/*******************************************************/
#include<stdio.h>
#include<stdlib.h>
main()
{
int n;
while(scanf("%d",&n)==1&&n!=0)
{
int temp[100],m,a,b;
for(a=0;a<n;a++)
{
scanf("%d",&temp[a]);
}
scanf("%d",&m);
for(a=0;a<n;a++)
{
for(b=0;b<n-1;b++)
{
if(temp[b]>temp[b+1])
{
int temp1;
temp1=temp[b];
temp[b]=temp[b+1];
temp[b+1]=temp1;
}
}
}
int set[100]={0};
for(a=0;a<m;a++)
set[a]=a+1;
for(a=0;a<m;a++)
printf("%d ",temp[set[a]-1]);
printf("\n");
int position=m-1;
if(m!=n)
{
while(1)
{
if(set[m-1]==n)
position--;
else
position=m-1;
set[position]++;
for(a=position+1;a<m;a++)
set[a]=set[a-1]+1;
for(a=0;a<m;a++)
printf("%d ",temp[set[a]-1]);
printf("\n");
if(set[0]>=n-m+1)
break;
}
printf("\n");
}
}
return 0;
}
/*
這些子集已經使用字典順序排列,如此才可以觀察出一些規則:
如果最右一個元素小於m,則如同碼錶一樣的不斷加1
如果右邊一位已至最大值,則加1的位置往左移
每次加1的位置往左移後,必須重新調整右邊的元素為遞減順序
所以關鍵點就在於哪一個位置必須進行加1的動作,到底是最右一個位置要加1?還是其它的位置?
在實際撰寫程式時,可以使用一個變數positon來記錄加1的位置,position的初值設定為n-1,因為我們要使用陣列,而最右邊的索引值為最大的n-1,在position位置的值若小於m就不斷加1,如果大於m了,position就減1,也就是往左移一個位置;由於位置左移後,右邊的元素會經過調整,所以我們必須檢查最右邊的元素是否小於m,如果是,則position調整回n-1,如果不是,則positon維持不變。
*/