以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  一个有趣的编程题目,1,2,5这三个数不同个数组合的和为1000的组合个数  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=26519)


--  作者:pennyliang
--  发布时间:1/17/2006 2:10:00 PM

--  一个有趣的编程题目,1,2,5这三个数不同个数组合的和为1000的组合个数
程序要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数。如:100个1是一个组合,5个1加19个5是一个组合。。。。
  请用C++语言写。

我的解法

定义三元组集合(x,y,z)上的偏函数,其中x,y,z都是正整数,满足(1,2,5)*(x,y,z)T=100, (x,y,z)T表示(x,y,z)转置。x+2y+5z=100。
  
  那么求该偏函数对应的集合的基数即是本题答案
  
  可知z最大取20,那么来看规律
  可能的答案为
  (0,0,20)
  (1,2,19)
  (3,1,19)
      (5,0,19)
  ....
  不难分析,答案为 1+ 求和(floor((5*i)/2)+1)[i从1,到20],
  算法复杂度为O(n),


原文连接
http://www5.tianya.cn/new/techforum/Content.asp?idWriter=2563455&Key=817608499&idItem=414&idArticle=1035


[此贴子已经被作者于2006-1-17 17:24:15编辑过]

--  作者:pennyliang
--  发布时间:1/20/2006 1:22:00 PM

--  

应该是(floor((5*i)/2)+1)[i从0,到20],特此更正
--  作者:qzlzj
--  发布时间:2/7/2006 9:16:00 PM

--  
学习 中...........
--  作者:bettyliu
--  发布时间:3/26/2006 11:12:00 AM

--  
嗯,不错,偏函数思想蛮不错的·~有兴趣可以去看看跳蚤程序玩玩~~有点类似的数学题~~
--  作者:firstway
--  发布时间:3/26/2006 1:03:00 PM

--  试着给出c代码(1)

//this is "sum100.h" writen by firstway

#include "stdio.h"
#define SUM_NUM 100
extern int NUMS[];


int do_1(int xyz[]);
int do_2(int xyz[]);
int do_3(int xyz[]);

int sum_into(int xyz[])
{
 if(xyz[0]<0)//未处理20的系数
 {
  do_1(xyz);
 }
 else if(xyz[1]<0)
 {
  do_2(xyz);
 }
 else if(xyz[2]<0)
 {
  do_3(xyz);
 }
 return 0;
}

int do_1(int xyz[])
{
 int cur_sum;
 int times;
 int i;
 
 cur_sum=SUM_NUM;
 times=cur_sum/NUMS[0];
 
 for(i=0;i<=times;i++)
 {
  xyz[0]=i;
  xyz[1]=-1;
  xyz[2]=-1;
  sum_into( xyz );
 }
 return 0;
}

int do_2(int xyz[])
{
 int cur_sum;
 int times;
 int i;
 
 cur_sum=SUM_NUM-xyz[0]*NUMS[0];
 times=cur_sum/NUMS[1];
 
 for(i=0;i<=times;i++)
 {
  xyz[1]=i;
  xyz[2]=-1;
  sum_into( xyz );
 }
 
 return 0;
}

int do_3(int xyz[])
{
 int cur_sum=SUM_NUM-xyz[0]*NUMS[0]-xyz[1]*NUMS[1];
 xyz[2]=cur_sum/NUMS[2];
 
 printf("(%2d, %2d, %2d)\n",xyz[0],xyz[1],xyz[2]);
 return 0;
}
// end of "sum100.h"


--  作者:firstway
--  发布时间:3/26/2006 1:04:00 PM

--  试着给出c代码(2)
//this is main()

#include "stdio.h"
#include "sum100.h"


int NUMS[]={5,2,1};

int main()
{

 int xyz[3]={-1,-1,-1};
 
 
 sum_into( xyz );
 
 return 0;
 
}

//end of main()


--  作者:firstway
--  发布时间:3/26/2006 1:19:00 PM

--  
结果应该有541条
right?
--  作者:elfstone
--  发布时间:3/26/2006 11:37:00 PM

--  


541是对的。。。
我写的算法,大家看一下。。。

#include "iostream"
using namespace std;
int main()
{
    int i,j,x,n=0;
    for(i=0;i<=20;i++)
    {
        x=100-i*5;
        for(j=0;j<=x/2;j++)
        {
            ++n;
            cout<<i<<' '<<j<<' '<<x-2*j<<endl;             
        }
    }
    cout<<"Total is:"<<n<<endl;
    system("PAUSE");
}


[此贴子已经被作者于2006-3-27 8:28:23编辑过]

--  作者:elfstone
--  发布时间:3/26/2006 11:42:00 PM

--  

firstway可能是受到楼主有关于偏函数说法的影响了,其实没必要用偏函数的。。。

题目要求的条件是 i+2*j+5*k==100 (i,j,k分别是1,2,5的个数)
稍变化一下就行了i==100-2*j-5*k(这样就可以减少不必要的运算,减少运算时间。。。)这就是我的算法思想。。。


[此贴子已经被作者于2006-3-27 8:25:12编辑过]

--  作者:firstway
--  发布时间:3/28/2006 3:05:00 PM

--  

是可以写的简单些
--  作者:elfstone
--  发布时间:3/28/2006 5:17:00 PM

--  
firstway是南大的?
--  作者:firstway
--  发布时间:3/28/2006 6:43:00 PM

--  

南大

--  作者:清风小筑
--  发布时间:11/30/2009 6:21:00 PM

--  
似乎远不止541.........应该有37880201

#include<iostream>
using namespace std;
main()
{
 int i,n,m,num=100,temp,y;
 for(i=0;i<=100;i++)
 for(n=0;n<=100;n++)
 for(m=0;m<=100;m++)
 {
  temp=(1*i+n*2+5*m);
  if(num==temp)
  {
   y++;
  }
 
  
 }
  cout<<y<<endl;
}


--  作者:清风小筑
--  发布时间:12/30/2009 8:28:00 AM

--  
抱歉...结果确实为541....
上述程序y应该置0......
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
93.750ms