如果数组为:1.21,1.42,1.68,1.10,1.55,1.87,1.38,1.25,1.88,1.91,1.64,1.33共12个数,要求使三个数之和共4组最接近,12个数都要用到(不重复),如何排出这种组合,为了区分,在排出的组合中要做好标志,如(1),(2),(3)...(12)对应数组中的数,这样如何能实现呢?这36个数可以放在一个a.txt文本里.盼高手帮忙解决!
调试欢乐多
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <limits.h>
int i,j,k;
int g[12][3]={//可能的分组大小
{ 1, 1,10},
{ 1, 2, 9},
{ 1, 3, 8},
{ 1, 4, 7},
{ 1, 5, 6},
{ 2, 2, 8},
{ 2, 3, 7},
{ 2, 4, 6},
{ 2, 5, 5},
{ 3, 3, 6},
{ 3, 4, 5},
{ 4, 4, 4},
};
int n[12];
int m[12];
int f[12];//当前最小时各数
int g1,g2,g3;//1,2,3组可分配的个数
int n1,n2,n3;//1,2,3组已分配的个数
int f1,f2;//当前最小时1,2组的个数
int s1,s2,s3;//123组的和
int d;//1-2,2-3,3-1组中各数和之间差的绝对值之和
int dmin=INT_MAX;//保存当前d的最小值
void swap(int *pi1,int *pi2) {
int t;
t=*pi1;*pi1=*pi2;*pi2=t;
}
void test() {
s1=0;
for (i=0;i<g1;i++) s1=s1+n[i];
s2=0;
for (i=g1;i<g1+g2;i++) s2=s2+n[i];
s3=0;
for (i=g1+g2;i<12;i++) s3=s3+n[i];
d=abs(s1-s2)+abs(s2-s3)+abs(s3-s1);
if (d<dmin) {
dmin=d;
f1=g1;
f2=g2;
for (i=0;i<12;i++) f[i]=n[i];
printf("(");
for (i=0;i<g1;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);
printf(") %4d\n",dmin);
} else {
printf("(");
for (i=0;i<g1;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);
printf(") %4d\n",d);
}
}
void main() {
srand(time(NULL));
for (i=0;i<12;i++) m[i]=rand()%100;
for (i=0;i<12;i++) printf("%2d,",m[i]);
printf("\n");
for (i=1;i<12;i++) {
for (j=0;j<i;j++) {
if (m[i]>m[j]) swap(&m[i],&m[j]);//冒泡排序从大到小
}
}
for (i=0;i<12;i++) printf("%2d,",m[i]);
printf("\n");
for (k=0;k<12;k++) {//在12种分组方法中
//取第i种分组方法
g1=g[k][0];
g2=g[k][1];
g3=g[k][2];
printf("%2d-%2d,%2d,%2d\n",k,g1,g2,g3);
//将从大到小12个数双向轮流分配到三个组中
n1=0;
n2=0;
n3=0;
for (j=0;j<12;j++) {
switch (j%6) {
case 0:
redo:
if (n1<g1) {
n[n1]=m[j];
n1++;
break;
}
case 1:
if (n2<g2) {
n[g1+n2]=m[j];
n2++;
break;
}
case 2:
if (n3<g3) {
n[g1+g2+n3]=m[j];
n3++;
break;
}
case 3:
if (n3<g3) {
n[g1+g2+n3]=m[j];
n3++;
break;
}
case 4:
if (n2<g2) {
n[g1+n2]=m[j];
n2++;
break;
}
case 5:
if (n1<g1) {
n[n1]=m[j];
n1++;
break;
}
default:goto redo;
}
}
test();
}
printf("---------------------------------------------------\n");
g1=f1;
g2=f2;
for (i=0;i<12;i++) n[i]=f[i];
printf("(");
for (i=0;i<g1;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1;i<g1+g2;i++) printf("%2d,",n[i]);
printf(") (");
for (i=g1+g2;i<12;i++) printf("%2d,",n[i]);
printf(") %4d\n",dmin);
}