| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 724 人关注过本帖
标题:求西瓜均分问题
只看楼主 加入收藏
the_second
Rank: 2
等 级:论坛游民
帖 子:115
专家分:80
注 册:2015-9-13
结帖率:78.95%
收藏
已结贴  问题点数:36 回复次数:8 
求西瓜均分问题
描述:地面上有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
……
注:均分的两堆如果只有摆放顺序不一样,算一种输出结果。
搜索更多相关主题的帖子: 设计程序 
2015-09-23 21:07
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
作业?
2015-09-23 21:19
the_second
Rank: 2
等 级:论坛游民
帖 子:115
专家分:80
注 册:2015-9-13
收藏
得分:0 
算是作业
2015-09-24 10:18
the_second
Rank: 2
等 级:论坛游民
帖 子:115
专家分:80
注 册:2015-9-13
收藏
得分:0 
#include <stdio.h>
void same(int s1[7],int s2[7])
{
    int sum1=0,sum2=0;
    int i;
    for(i=0;i<6;i++)
    {
        sum1=sum1+s1[i];
        sum2=sum2+s2[i];
    }
    if(sum1==sum2)
    {
        for(i=0;i<6;i++)
            printf("%d ",s1[i]);
        printf("|");
        for(i=0;i<6;i++)
            printf("%d ",s1[i]);
    }
}
void scpy(int s1[7],int num[13])
{
    int i,j,k,l;
    int s2[7];
    l=0;
    for(i=0;i<13;i++)
    {
        k=0;
        for(j=0;j<6;j++)
        {
            if(num[i]!=s1[j])
            {
                k++;
            }
        }
        if(k==6)
        {
            s2[l]=num[i];
            l++;
        }
    }
    same(s1,s2);
}
int main()
{
    int num[13]={98,93,57,64,50,82,18,34,69,56,16,61};
    int s1[7];
    int i,j,k,l,m,n;
    for(i=0;i<6;i++)
    {
        s1[0]=num[i];
        for(j=i+1;j<7;j++)
        {
            s1[1]=num[j];
            for(k=j+1;k<8;k++)
            {
                s1[2]=num[k];
                for(l=k+1;l<9;l++)
                {
                    s1[3]=num[l];
                    for(m=l+1;k<10;m++)
                    {
                        s1[4]=num[m];
                        for(n=m+1;n<11;n++)
                        {
                            s1[5]=num[n];
                            scpy(s1,num);
                        }
                    }
                }
            }
        }
    }
    return 0;
}
2015-09-24 10:19
the_second
Rank: 2
等 级:论坛游民
帖 子:115
专家分:80
注 册:2015-9-13
收藏
得分:0 
我只会用大量的for循环,用时会很长
2015-09-24 10:20
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
可惜是作业


[fly]存在即是合理[/fly]
2015-09-24 11:09
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9031
专家分:54061
注 册:2011-1-18
收藏
得分:36 
使用暴力遍历,先用C++,因为C++直接提供了排列组合函数std::next_permutation
其思路算法以注释的形式包含在代码中
程序代码:
#include <cstdio>
#include <algorithm>

int main( void )
{
    const unsigned num[12] = { 98, 93, 57, 64, 50, 82, 18, 34, 69, 56, 16, 61 };
    // 第一个放左边,再从余下的西瓜中挑出5个放左边,使这5个数的和等于 “总数/2 - 第一个瓜”
    unsigned sum = 0;
    {
        for( size_t i=0; i!=12; ++i )
            sum += num[i];
        if( sum%2 != 0 )
            return 1;
        sum = sum/2 - num[0];
    }

    // 遍历下面mask数组的各种排列组合(0代表选中,1代表不选中),从中挑选出符合题目要求的输出
    int mask[11] = { 0,0,0,0,0,1,1,1,1,1,1 };
    do
    {
        // 计算累加和
        unsigned sum2 = 0;
        for( size_t i=0; i!=11; ++i )
            if( mask[i] == 0 )
                sum2 += num[i+1];
        if( sum2 != sum )
            continue;

        // 输出
        printf( "%02d", num[0] );
        for( size_t i=0; i!=11; ++i )
            if( mask[i] == 0 )
                printf( ", %02d", num[i+1] );
        printf( "\n" );

    } while( std::next_permutation(mask,mask+11) );

    return 0;
}

在C语言中,只需要自己写个相似的算法来替代std::next_permutation,代码如下
程序代码:
#include <stdio.h>
#define bit_next(a) (((((((a)-1)|(a))^(1+(((a)-1)|(a))))&(a))/(1+(((a)-1)^(a))))|(1+(((a)-1)|(a))))

int main( void )
{
    const unsigned num[12] = { 98, 93, 57, 64, 50, 82, 18, 34, 69, 56, 16, 61 };
    // 第一个放左边,再从余下的西瓜中挑出5个放左边,使这5个数的和等于 “总数/2 - 第一个瓜”
    unsigned sum = 0;
    {
        for( size_t i=0; i!=12; ++i )
            sum += num[i];
        if( sum%2 != 0 )
            return 1;
        sum = sum/2 - num[0];
    }

    // 遍历{ 0,0,0,0,0,1,1,1,1,1,1 }的各种排列组合(0代表选中,1代表不选中),从中挑选出符合题目要求的输出
    for( unsigned a=0x3F; a!=0x81F; a=bit_next(a) ) // from 00000111111B to 100000011111B
    {
        // 计算累加和
        unsigned sum2 = 0;
        for( size_t i=0; i!=11; ++i )
            if( (a&(1<<(11-1-i))) == 0 )
                sum2 += num[i+1];
        if( sum2 != sum )
            continue;

        // 输出
        printf( "%02d", num[0] );
        for( size_t i=0; i!=11; ++i )
            if( (a&(1<<(11-1-i))) == 0 )
                printf( ", %02d", num[i+1] );
        printf( "\n" );
    }

    return 0;
}

输出是
98, 93, 50, 18, 34, 56
98, 50, 82, 34, 69, 16
98, 82, 18, 34, 56, 61

2015-09-25 10:05
the_second
Rank: 2
等 级:论坛游民
帖 子:115
专家分:80
注 册:2015-9-13
收藏
得分:0 
多谢了
2015-09-26 12:11
快速回复:求西瓜均分问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021728 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved