7-3 CillyB的简单的送分题~(20 分)
众所周知,CillyB是一个学习每次年级前十,算法又无敌的人,他现在学习的学的累了,所以想做一个思维题放松下(对就是做思维题放松),他随便找了n个非0的个位数字,用其中任意3个数字都可以组合成1个3位的数字(但是三个位数上的数字不能相同)。要求所有可能组合出来的3位数字的和。例如给定2、5、8,则可以组合出:258、285、528、582、825、852,它们的和为3300。
输入格式:
输入在一行中先给出N(3 <=N<=9),随后是N个不同的非0个位数字。数字间以空格分隔。
输出格式:
输出所有可能组合出来的3位数字的和,并且独占一行。
输入样例:
3 2 5 8
输出样例:
3330
这个题的难点主要在n个数字任意3个数字组合,这要求不能是重复的3个数字,所以说这就需要高中学的排列组合,拿出不重复的三位数字。
方法一:
三位数字就是从输入的书中依次挑,第一次挑:第一个第二个第三个,第二次挑:第一个第二个第四个,这样下去,主键第二位变成了第三个:第一个第三个第四个,这样安顺序一直挑下去就不会重复。
三位数字要组成3位数有6中组合方法,把每种组合方式都写出来求和就得到了这个三位数组合的和,然后在去其他三位数的和。
#include<stdio.h> int main() { int n,i,j,k,sum; int *p; scanf("%d",&n); p=(int *)malloc(n*sizeof(int)); for(i=0;i<n;i++) scanf("%d",&p[i]); for(i=0;i<n;i++) \\这里就是按照上面的方法挑3位数 { for(j=i+1;j<n;j++) \\第二层for循环,是从上一层i+1开始的,一位置这样就不重复了 { for(k=j+1;k<n;k++) \\第三层for循环是在第二层j+1开始的,这样也不会重复 { sum+=(p[i]*100+p[j]*10+p[k])+(p[i]*100+p[k]*10+p[j])+(p[j]*100+p[i]*10+p[k])+(p[j]*100+p[k]*10+p[i])+(p[k]*100+p[j]*10+p[i])+(p[k]*100+p[i]*10+p[j]); } } } printf("%d",sum); return 0; }方法二:
第二种方法是根本不挑三位数,只要将用三个for循环,并在第三个for循环里计算从外向里依次是百位十位个位的数值,在这之前需要判断不能重复,这样下去虽然不是挑出三个三个的来组合,但是利用for循环仍然可以不漏的把各种情况都算进去。
#include<stdio.h> int main() { int n,i,j,k,sum=0; int *p; scanf("%d",&n); p=(int *)malloc(n*sizeof(int)); for(i=0;i<n;i++) scanf("%d",&p[i]); for(i=0;i<n;i++) { for(j=0;j<n;j++) { for(k=0;k<n;k++) { if(p[i]!=p[j]&&p[j]!=p[k]&&p[i]!=p[k]) \\盘是否重复,不能实现重复 sum+=(p[i]*100+p[j]*10+p[k]); \\p[i]是百位,p[j]是十位,p[k]是个位。 } } } printf("%d",sum); return 0; }