题目描述
编写程序实现用一元硬币换成一分,两分,五分的硬币共50枚。
思路
假设一分,两分,五分的硬币各X,Y,Z枚。则有
1.X+Y+Z=50;
2,X+2Y+5Z=100;
3,X在(0,50),Y在(0,50),Z在(0,20)范围内
这里提一下O(n)算法,可以借助上述公式得出
Y=50-4Z;
X=3Z;
代码:
#include<stdio.h>
void method1()//O(n3)
{
int ans=0;
for(int i=0;i<=50;i++)//一分的数量
for(int j=0;j<=50;j++)//两分的数量
for(int k=0;k<=20;k++)//五分的数量
if(i+j+k==50 && i+2*j+5*k==100)
printf("一分:%d 两分:%d 五分:%d\n",i,j,k),ans++;
printf("总共有%d种方法\n",ans);
}
void method2()//O(n2)
{
int ans=0;
for(int i=0;i<=50;i++)//两分的数量
{
for(int j=0;j<=20;j++)//五分的数量
{
int x=50-i-j;//一分的数量
if(x>=0 && i+4*j==50)
{
printf("一分:%d 两分:%d 五分:%d\n",x,i,j);
ans++;
}
}
}
printf("总共有%d种方法\n",ans);
}
void method3()//O(n)
{
int ans=0;
for(int i=0;i<=12;i++)//五分钱的数量
{
int j=50-4*i;//两分钱
int k=3*i;//一分钱
printf("一分:%d 两分:%d 五分:%d\n",k,j,i),ans++;
}
printf("总共有%d种方法\n",ans);
}
int main()
{
//method1();
//method2();
method3();
return 0;
}
题目描述
我国古代数学家张邱建在《算法》中出了一道题“鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。百钱百鸡,问鸡翁,鸡母,鸡雏各几何?”
现在假定各鸡种的价格不变,拥有的钱数为m,需要购买的鸡数为n,试求出所有可能的购买方案数。
input
每行对应一个测试样例,每一行包含2个数字,分别为n和m。最后一行包含2个-1,表示输入结束。
output
每组测试样例的结果输入占一行,输出可能购买方案的总数。
思路:
首先暴力来做这个题,设i为公鸡,j为母鸡,k为小鸡,就满足两个条件
1.n=i+j+k;
2.m=5i+3j+k/3;这里的k一定要是3的公倍数;
代码(n³)
#include<stdio.h>//这个算法的时间复杂度可以认为是O(n3)
int main()
{
int m,n;
while(scanf("%d%d",&n,&m),n!=-1)
{
int cnt=0;
for(int i=0;i<=n;i++)//i代表的公鸡数量
for(int j=0;j<=n;j++)//j代表的母鸡数量
for(int k=0;k<=n;k++)//k代表小鸡数量
if(i*5+j*3+k/3==m && k%3==0 && i+j+k==n)
cnt++;//printf("%d %d %d\n",i,j,k);
printf("%d\n",cnt);
}
return 0;
}
很容易看出来这是一个n³的算法;如何改进,我们可以想到i,j,k是不独立的,满足m=5i+3j+k/3,所以k=3m-15i-9*j;时间复杂度就降了一维;
代码(n²)
#include<stdio.h>//假设我们能买到n个鸡,则小鸡的数量为k=n-i-j; m=i*5+j+k/3=>k=3*m-15*i-3*j;
int main()
{
int m,n;
while(scanf("%d%d",&n,&m),n!=-1)
{
int cnt=0;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
{
int k=3*m-15*i-9*j;
if(k>=0 && i+j+k==n) cnt++;//printf("%d %d %d\n",i,j,k);
}
printf("%d\n",cnt);
}
}
已知
1.n=i+j+k;
2.m=5i+3j+k/3;这里的k一定要是3的公倍数;
推出
1.8k=6i-3m+9n;
2.8j=3m-n-14j;
代码(n)
#include<stdio.h>
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),n!=-1)
{
int cnt=0;
for(int i=0;i<=m/5;i++)
{
int k=6*i-3*m+9*n;
int j=3*m-n-14*i;
if(k%8==0 && j%8==0 &&j>=0 && k>=0)
{
printf("%d %d %d\n",i,j/8,k/8);
cnt++;
}
}
printf("%d\n",cnt);
}
return 0;
}