<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->
/**************************************************************
程序名: Sum It Up
作者:许文发
时间: 2009-11-26
描述:给定一整数 t ,在 list 数组中找到和为 t 的所有组合
**************************************************************/
#include<iostream.h>
#include<stdio.h>
#include<string.h>
int num=0; // 每组所有组合总数
int first=1; // 第一次输出
// 求和
int sum(int add[],int count)
{
int result=0;
for(int i=0;i<count;i++)
result+=add[i];
return result;
}
// 按从大到小排序
void sort(int list[],int n)
{
int temp;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(list[i]<list[j])
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}
}
// 判断一维数组 test 是否在二维数组 totalList 中,返回 1 表示在,返回 0 表示不在
int isExist(int totalList[][12],int num,int test[],int n)
{
int result;
for(int i=0;i<num;i++)
{
result=0;
for(int j=0;j<n;j++)
if(totalList[i][j]==test[j])
result++;
if(result==n)
{
return 1;
break;
}
}
return 0;
}
// 将一维数组 test 填到二维数组 totalList 中
void copyArray(int totalList[][12],int num,int test[],int n)
{
int i;
for(i=0;i<n;i++)
{
totalList[num][i]=test[i];
}
}
// 主要算法(递归)
void sumItUp(int list[],int ii,int total,int t,int n,int add[],int count,int totalList[][12])
{
// 先判断是否出界
if(ii<=n)
{
// 判断组合是否正确
if(total==sum(add,count))
{
if(!isExist(totalList,num,add,count))
{
copyArray(totalList,num,add,count);
num++;
}
}
else
{
add[count++]=list[ii];
if(sum(add,count)<=total)
sumItUp(list,ii+1,total,t-list[ii],n,add,count,totalList);
count--;
add[count]=0;
sumItUp(list,ii+1,total,t,n,add,count,totalList);
}
}
}
// 清文件
void clearfile()
{
FILE *pt;
pt=fopen("output.txt","w");
fclose(pt);
}
// 写文件
void mywrite(int totalList[][12],int num,int total)
{
FILE *pt;
pt=fopen("output.txt","a");
int i,j;
if(!first)
fprintf(pt,"/n");
fprintf(pt,"Sums of %d:/n",total);
if(num==0)
{
fprintf(pt,"NONE");
}
else
{
int linefirst;
int end=0;
for(i=0;i<num;i++)
{
if(i==num-1)
end=1;
linefirst=1;
for(j=0;j<12;j++)
{
if(totalList[i][j]==0)
break;
else
{
if(!linefirst)
fprintf(pt,"+");
fprintf(pt,"%d",totalList[i][j]);
}
linefirst=0;
}
if(!end)
fprintf(pt,"/n");
}
}
fclose(pt);
}
void main()
{
FILE *pt;
int t; // 数和
int n; // 数组中数的数目
int i,j;
int list[12]; // 用于存放数组
int add[12]; // 用于存放临时组合
int totalList[100][12];// 用于存放每组数据所有组合
clearfile();
if(NULL==(pt=fopen("input.txt","r")))
{
cout<<"can't open input.txt!"<<endl;
}
else
{
fscanf(pt,"%d",&t);
fscanf(pt,"%d",&n);
while(!(t==0 && n==0))
{
for(i=0;i<n;i++)
fscanf(pt,"%d",&list[i]);
sort(list,n);
memset(add,0,sizeof(add));
num=0;
for(i=0;i<100;i++)
{
for(j=0;j<12;j++)
totalList[i][j]=0;
}
sumItUp(list,0,t,t,n,add,0,totalList);
mywrite(totalList,num,t);
first=0;
fscanf(pt,"%d",&t);
fscanf(pt,"%d",&n);
}
}
}
输入:
5 3 2 1 1
4 6 4 3 2 2 1 1
400 12 50 50 50 50 50 50 25 25 25 25 25 25
0 0
输出:
Sums of 5:
NONE
Sums of 4:
4
3+1
2+2
2+1+1
Sums of 400:
50+50+50+50+50+50+25+25+25+25
50+50+50+50+50+25+25+25+25+25+25