程序员面试题精选{57):求n的加法组合
来源:互联网 发布:office办公软件培训班 编辑:程序博客网 时间:2024/04/29 03:56
一个正整数n可以写为几个正整数的和,如:
4=4
4=3+1
4=2+2
4=2+1+1
4=1+1+1+1
输入一个正整数,找出符合这种要求的所有正整数序列(序列不重复)
算法思想:
以n=6为例,将数继序列暂时存于a[MAXCOL]中,且初始时值全为1。
对数组中从jcol列开始的newn个元素进行操作f(6,0,0) ——函数GetCombinations(newn,newj,col)
col记录调用该函数时是在第col列。
初始化
count=6
j=0,newn=0
count=n
1. 如果count>1,令a[jcol]=count;
若count>a[col],表明该尝试不满足条件,count=count-1,重复1;
否则将该行第jcol+1列到jcol+count-1列的值改为0;
否则,退出;
2. newn=n-count
3. 如果new>1,则对从该行开始从jcol+count开始的newn个元素进行类似操作,并返回该新的newn对应的序列个数;
否则,count=count-1,返回1。
算法比较:
“acm题目及我的程序(3)——正整数n的加法组合”——使用二维数组存放加法序列
#define MAXROW 12000
#define MAXCOL 20
#define MAXCOL 20
a[MAXROW][MAXCOL]
算法效率低,空间浪费严重
“acm题目及我的程序(3)——正整数n的加法组合(改进)”——使用二维数组存放加法序列
a[MAXROW][MAXCOL]
#define MAXROW 6000
#define MAXCOL 30
#define MAXCOL 30
算法效率高,空间浪费不严重
“acm题目及我的程序(3)——正整数n的加法组合(改进2)”——使用动态二维数组存放加法序列
vector<vector<int> > m_venline
算法效率高,空间浪费很少
本文算法——使用一维数组存放加法序列,且计算每个n的加法序列的个数
a[MAXCOL]
算法效率最高,空间根本不浪费
代码如下:
/**//************************************************************************
* 一个正整数n可以写为几个正整数的和
* 4=4
* 4=3+1
* 4=2+2
* 4=2+1+1
* 4=1+1+1+1
* 要求:输入一个正整数,找出符合这种要求的所有正整数序列(序列不重复)
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <CONIO.H>
#include <vector>
using namespace std;
#define MAXCOL 80
#define FILENAMELENGTH 100
class AdditionCombination
...{
public:
int a[MAXCOL];
int m_number; //条用GetCombinations函数时count的值
public:
AdditionCombination(int number)
...{
m_number=number;
for(int j=0;j<MAXCOL;j++)
a[j]=1;
}
~AdditionCombination()...{}
void Initialize()
...{
for(int j=0;j<m_number;j++)
a[j]=1;
}
void Initialize(int jcol)
...{
for(int j=jcol;j<m_number;j++)
a[j]=1;
}
int GetCombinations(int n,int jcol,int col);
void display(int n);
};
//在数组中从irow行,jcol列开始对n阶子矩阵进行
//col记录调用该函数前jcol的值
int AdditionCombination::GetCombinations(int n,int jcol,int col)
...{
int nTotalCount=0;
int j=0,newn=0;
int count=n;
while(count>1)
...{
if(jcol==0)
Initialize();
else
Initialize(jcol);
a[jcol]=count;
//算法优化,删除不满足的序列
if(a[jcol]>a[col])
...{
count--;
continue;
}
for(j=jcol+1;j<jcol+count;j++)
a[j]=0;
newn=n-count;
if(newn>1)
...{
int newj=jcol+count;
int newcount=GetCombinations(newn,newj,jcol);
nTotalCount+=newcount;
}
count--;
//display(m_number);
nTotalCount++;
}
if(jcol==0)
...{
Initialize();
//display(m_number);
nTotalCount++;
}
else
Initialize(jcol);
return nTotalCount;
}
void AdditionCombination::display(int n)
...{
printf(" %d=%d",n,a[0]);
for(int j=1;j<n;j++)
...{
if(a[j])
printf("+%d",a[j]);
}
}
//将结果写入文件
void WriteToFile(vector<vector<int> > info)
...{
char filename[FILENAMELENGTH];
int size=info.size();
//构造文件名
sprintf(filename,"%d-%d result.txt",info[0][0],info[size-1][0]);
FILE *fp=fopen(filename,"w");
if(fp==NULL)
...{
printf("can not wirte file!");
exit(0);
}
//写入个数
for(int i=0;i<size;i++)
fprintf(fp,"n=%d count=%d ",info[i][0],info[i][1]);
fclose(fp);
}
//显示菜单
void show_menu()
...{
printf("--------------------------------------------- ");
printf("input command to test the program ");
printf(" i or I : input n to test ");
printf(" t or T : get count from n1 to n2 ");
printf(" q or Q : quit ");
printf("--------------------------------------------- ");
printf("$ input command >");
}
void main()
...{
char sinput[10];
int n;
show_menu();
scanf("%s",sinput);
while(stricmp(sinput,"q")!=0)
...{
if(stricmp(sinput,"i")==0)
...{
printf(" please input an integer:");
scanf("%d",&n);
AdditionCombination obj(n);
int count=obj.GetCombinations(n,0,0);
printf(" count = %d ",count);
}
else if(stricmp(sinput,"t")==0)
...{
int n1,n2;
printf(" please input the begin number:");
scanf("%d",&n1);
printf(" please input the end number:");
scanf("%d",&n2);
printf(" press any key to start ... ");
getch();
vector<vector<int> > info;
vector<int> line;
AdditionCombination obj(n1);
for(int i=n1;i<=n2;i++)
...{
obj.Initialize();
obj.m_number=i;
int count=obj.GetCombinations(i,0,0);
printf(" n=%d count=%d ",i,count);
line.clear();
line.push_back(i);
line.push_back(count);
info.push_back(line);
}
printf(" ");
//写入文件
printf("$ write the numbers to file(Y,N)? >");
scanf("%s",sinput);
if(stricmp(sinput,"y")==0) //写入文件
...{
WriteToFile(info);
printf(" write successfully! ");
}
printf(" ");
}
//输入命令
printf("$ input command >");
scanf("%s",sinput);
}
}
* 一个正整数n可以写为几个正整数的和
* 4=4
* 4=3+1
* 4=2+2
* 4=2+1+1
* 4=1+1+1+1
* 要求:输入一个正整数,找出符合这种要求的所有正整数序列(序列不重复)
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <CONIO.H>
#include <vector>
using namespace std;
#define MAXCOL 80
#define FILENAMELENGTH 100
class AdditionCombination
...{
public:
int a[MAXCOL];
int m_number; //条用GetCombinations函数时count的值
public:
AdditionCombination(int number)
...{
m_number=number;
for(int j=0;j<MAXCOL;j++)
a[j]=1;
}
~AdditionCombination()...{}
void Initialize()
...{
for(int j=0;j<m_number;j++)
a[j]=1;
}
void Initialize(int jcol)
...{
for(int j=jcol;j<m_number;j++)
a[j]=1;
}
int GetCombinations(int n,int jcol,int col);
void display(int n);
};
//在数组中从irow行,jcol列开始对n阶子矩阵进行
//col记录调用该函数前jcol的值
int AdditionCombination::GetCombinations(int n,int jcol,int col)
...{
int nTotalCount=0;
int j=0,newn=0;
int count=n;
while(count>1)
...{
if(jcol==0)
Initialize();
else
Initialize(jcol);
a[jcol]=count;
//算法优化,删除不满足的序列
if(a[jcol]>a[col])
...{
count--;
continue;
}
for(j=jcol+1;j<jcol+count;j++)
a[j]=0;
newn=n-count;
if(newn>1)
...{
int newj=jcol+count;
int newcount=GetCombinations(newn,newj,jcol);
nTotalCount+=newcount;
}
count--;
//display(m_number);
nTotalCount++;
}
if(jcol==0)
...{
Initialize();
//display(m_number);
nTotalCount++;
}
else
Initialize(jcol);
return nTotalCount;
}
void AdditionCombination::display(int n)
...{
printf(" %d=%d",n,a[0]);
for(int j=1;j<n;j++)
...{
if(a[j])
printf("+%d",a[j]);
}
}
//将结果写入文件
void WriteToFile(vector<vector<int> > info)
...{
char filename[FILENAMELENGTH];
int size=info.size();
//构造文件名
sprintf(filename,"%d-%d result.txt",info[0][0],info[size-1][0]);
FILE *fp=fopen(filename,"w");
if(fp==NULL)
...{
printf("can not wirte file!");
exit(0);
}
//写入个数
for(int i=0;i<size;i++)
fprintf(fp,"n=%d count=%d ",info[i][0],info[i][1]);
fclose(fp);
}
//显示菜单
void show_menu()
...{
printf("--------------------------------------------- ");
printf("input command to test the program ");
printf(" i or I : input n to test ");
printf(" t or T : get count from n1 to n2 ");
printf(" q or Q : quit ");
printf("--------------------------------------------- ");
printf("$ input command >");
}
void main()
...{
char sinput[10];
int n;
show_menu();
scanf("%s",sinput);
while(stricmp(sinput,"q")!=0)
...{
if(stricmp(sinput,"i")==0)
...{
printf(" please input an integer:");
scanf("%d",&n);
AdditionCombination obj(n);
int count=obj.GetCombinations(n,0,0);
printf(" count = %d ",count);
}
else if(stricmp(sinput,"t")==0)
...{
int n1,n2;
printf(" please input the begin number:");
scanf("%d",&n1);
printf(" please input the end number:");
scanf("%d",&n2);
printf(" press any key to start ... ");
getch();
vector<vector<int> > info;
vector<int> line;
AdditionCombination obj(n1);
for(int i=n1;i<=n2;i++)
...{
obj.Initialize();
obj.m_number=i;
int count=obj.GetCombinations(i,0,0);
printf(" n=%d count=%d ",i,count);
line.clear();
line.push_back(i);
line.push_back(count);
info.push_back(line);
}
printf(" ");
//写入文件
printf("$ write the numbers to file(Y,N)? >");
scanf("%s",sinput);
if(stricmp(sinput,"y")==0) //写入文件
...{
WriteToFile(info);
printf(" write successfully! ");
}
printf(" ");
}
//输入命令
printf("$ input command >");
scanf("%s",sinput);
}
}
- 程序员面试题精选{57):求n的加法组合
- 程序员面试题精选{57):求n的加法组合
- 程序员面试题精选(8):求1+2+...+n
- 程序员面试题精选(44):整数分割(即求一个数N由小于等于N的数相加所得的所有组合)
- 程序员面试题精选-- 字符串的组合
- 程序员面试题精选-- 字符串的组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题(59)-字符串的组合
- 程序员面试题精选100题-字符串的组合[算法]
- 程序员面试题精选100题:求从1到n的正数中1出现的次数
- 程序员面试题精选(47):两个或N个数的最大公约数和最小公倍数的求解
- 程序员面试题精选100题(57)-O(n)时间的排序
- .程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序
- 程序员面试题精选100题(57)-O(n)时间的排序
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- web 2.0 简介
- Tailrank 网站架构
- J2SE综合:深入了解Java 5.0的垃圾收集
- 小工具集_运行时截图
- [笔记/简译]XAML揭秘(4)
- 程序员面试题精选{57):求n的加法组合
- 进阶--学习J2SE过程中的30个基本概念 来源:赛迪网 作者:2277802
- 密室逃脱系列
- [笔记/简译]XAML揭秘(5)
- 今天去了公公单位
- 程序员面试题精选{57):求n的加法组合
- Web缓存加速指南
- TOMCAT6 JSP MSSQL 连接报错情况以及解决方法
- WikiPedia 技术架构学习分享