首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

求大牛,请问一个算法有关问题

2012-09-25 
求大牛,请教一个算法问题2.求西瓜均分问题。(70分)描述:地面上有12个西瓜,它们的重量(单位为“两”,为计算方

求大牛,请教一个算法问题
2.求西瓜均分问题。(70分) 
描述:地面上有12个西瓜,它们的重量(单位为“两”,为计算方便已全部转化为整数,如98即为9斤8两)如下: 
98,93,57,64,50,82,18,34,69,56,16,61
(1)设计程序:实现对以上12个瓜“二堆均分”(每堆6个,两堆重量相等),要求打印输出均分的各种可能方案; 
(a)输入:数据输入由程序完成,执行程序后不需要任何数据输入; 
(b)输出:程序执行后输出以下格式, X分别代表一个西瓜重量的数字,如下: 
No1:X X X X X X,X X X X X X
No2:X X X X X X,X X X X X X
……
注:均分的两堆如果只有摆放顺序不一样,算一种输出结果。 
(30分) 

(2)设计程序,实现对以上12个西瓜,拟实现“三堆均分”(每堆4个,三堆重量相等)。考虑到上述西瓜总重量不能为3所整除,这里另有几个西瓜,重量分别为:70,71,72,73,74,75可供挑选,从12个西瓜中替换掉其中一个,是否可以实现“三堆均分”?如果可以,设计程序实现,要求打印输出均分的各种可能方案; 
(a)输入:数据输入由程序完成,执行程序后不需要任何数据输入; 
(b)输出:输出结果为以下格式,X分别代表一个西瓜重量的数字,A、B、C、D、E分别代表替换原来西瓜的新重量数字70、71、72、73、74、75,如下 : 
No1(A replaces X):X X X X,X X X X,X X X X
No2(B replaces X):X X X X,X X X X,X X X X
……



[解决办法]
还挺复杂的,写了将近一个小时,看来水平下降了!

C/C++ code
#include <iostream>using namespace std;#define N 12#define M 6void qsort_one_fun(int a[], int begin, int end){    if (begin<end)    {                int b=begin;        int e=end;        int temp=a[b];        while(b<e)        {            while (b<e && a[e]>=temp)            {                e--;            }            a[b]=a[e];            while (b<e && a[b]<=temp)            {                b++;            }            a[e]=a[b];        }        a[b]=temp;        qsort_one_fun(a, begin, e-1);        qsort_one_fun(a, e+1, end);    }    return;    }void cnm_sum(int n, int m, int *r){    int lib[999][M];    int pos_lib = 0;    int temp[M];    int r_sum = 0;    int i;    for(i=0; i<n; ++i)    {        r_sum += r[i];    }    int *a = new int[m];    if (a==NULL)    {        return;    }    int pos = 0;    a[pos] = 0;    while (true)    {        while (!(a[pos]>n-1 || pos>=m-1))        {                    a[pos+++1] = a[pos] + 1;        }        if (a[pos]>n-1)        {            if (pos>0)            {                a[--pos]++;            }            else            {                break;            }                }        else        {            int sum = 0;            while (pos>=0)            {                sum += r[a[m-1-pos--]];            }                        if(2*sum==r_sum)            {                int i;                for(i=0; i<m; ++i)                {                    temp[i] = r[a[i]];                }                qsort_one_fun(temp, 0, m-1);                for(i=0; i<pos_lib; ++i)                {                    int j;                    for(j=0; j<m && lib[i][j]==temp[j]; ++j);                    if(j==m)                    {                        break;                    }                                    }                if(i==pos_lib)                {                    int j;                    for(j=0; j<m; ++j)                    {                        lib[pos_lib][j] = temp[j];                    }                    ++pos_lib;                    int pos2 = 0;                    for(j=0; j<n; ++j)                    {                        int k;                        for(k=0; k<m && j!=a[k]; ++k);                        if(k==m)                        {                            lib[pos_lib][pos2] = r[j];                            ++pos2;                        }                    }                    qsort_one_fun(lib[pos_lib], 0, m-1);                    ++pos_lib;                }            }            a[pos=m-1]++;        }    }    for(i=0; i<pos_lib; ++i)    {        int j;        for(j=0; j<m-1; ++j)        {            cout<<lib[i][j]<<" ";        }        cout<<lib[i][j];        if((i&1)==0)        {            cout<<", ";        }                if(i>0 && (i&1)==1)        {            cout<<endl;        }    }}int main(){    int r[N] = {98,93,57,64,50,82,18,34,69,56,16,61};    cnm_sum(N, M, r);    return 0;} 


[解决办法]
仅供参考

C/C++ code
//给出12个随机数,分成三组求和,每组的个数不定,要求求出来的三个数之间相差最小,最完美的情况是三个数相等.#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);} 

热点排行