从5种不同颜色的球中取三个球,要求这三个球每个颜色都不一样,问:有多少种取法?用C语言或伪代码实现.

关键是要排除排列的影响,
如果直接用三个for循环来处理的话,会出现red,black,white和white,black,red是两种取法这一现象(其实只属于一种).
请C高手帮帮忙(尤其是算法工程师)!

这个问题可以用二进制位来表示

5个二进制位代表五种颜色的球
要找的组合就是三个位是1两个位是0的那部分

#include <stdio.h>

int main(void)
{
int i;
int count;
int n = 0;
for (i = 7; i <= 28; i++)
{
count = 0;
if ((i & 1) == 1)
count++;
if ((i & 2) == 2)
count++;
if ((i & 4) == 4)
count++;
if ((i & 8) == 8)
count++;
if ((i & 16) == 16)
count++;

if (count == 3)
{
printf("%d\n", i);
n++;
}

}
printf("\n%d", n);

}

7 二进制 是 111
28 二进制 是 11100
因为是5取三 所以循环从7 到 28

结果是 10 种
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-05-25
#include <stdio.h>
void main()
{
enum color{red,yellow,blue,while,blace};
enum color i,j,k,pri;
int n,loop;
n=0;
for(i=red;i<=black;i++)
for(j=red;j<=blace;j++)
if(i!=j) //这句是关键!
{
for(k=red;k<=blace;k++)
if((k!=i)&&(k!=j)) //这句亦是关键!
{
n=n+1; //用于表示共有多少种组合!
printf("%-4d",n);
for(loop=1;loop<=3;loop++)
{
switch(loop)
{
case 1 :pri=i;break;
case 2 :pri=j;break;
case 3 :pri=k;break;
default break;
}
switch(pri)
{
case red: printf("%-10s","red");break;
case yellow: printf("%-10s","yellow");break;
case blue: printf("%-10s","blue");break;
case white:printf("%-10s","white");break;
case black:printf("%-10s","blace");break;
default :break;
}
}
printf("\n");
}
}
printf("\ntotal:%5d\n",n); //共有60种组合!
}
第2个回答  2009-05-25
1楼正解
2楼的算排列了,不对
3楼的做法对,看似效率高,其实不然
仔细分析,3楼的公式的复杂度和1楼一样,但1楼用的是耗时最少的运算:位运算,而3楼则要做乘法;并且做阶层的结果很可能太大,导致一般数据类型无法存放
第3个回答  2009-05-25
就是5个球里取出3个来,有几种方法。
5!/(3!*2!),写个阶乘的程序算一下就行。
第4个回答  2009-05-25
二楼的答案有重复的,算法不对
相似回答