6 条题解
-
2
通读题目后,不难发现:如果买完奖品A与B后钱数还有剩余,可买奖品C“填补”剩余钱数直到钱花完(因为奖品C单价为1元),之后再判断总量是否大于30即可。因此,只需枚举奖品A与奖品B的数量即可(双重for循环)主要代码如下:
/* i为奖品A数量 j为奖品B数量 k为奖品C数量 sum为总方案数 */ for (int i = 1 ; i <= n / a ; i++) { for (int j = 1 ; j <= n / b ; j++) { int k = n - (i * a + j * b); if (a * i + b * j < n && i + j + k > 30) { sum++; } } }
-
1
就喜欢van一van高级代码()
DFS深度优先搜索算法解题#include<bits/stdc++.h> using namespace std; int n,a,b,total; // total为方案数 /* * kind --- 种类 * num --- 物品总数 * money --- 剩余金钱 */ void dfs(int kind,int num,int money){ if(kind>3){ // 已经买齐3种物品 if(num>30&&money==0)total++; // 满足题目条件时 return; // 返回 } if(money<=0)return; // 剪枝优化:金钱小于等于0且未买齐3种物品说明不必再往后搜索 // 按照种类进行搜索 if(kind==1) for(int i=1;i<=money/a;i++) // 尝试所有物品都买A dfs(2,num+i,money-a*i); else if(kind==2) for(int i=1;i<=money/b;i++) // 尝试所有物品都买B dfs(3,num+i,money-b*i); else if(kind==3) for(int i=1;i<=money;i++) // 尝试所有物品都买C dfs(4,num+i,money-i); } int main(){ cin>>n>>a>>b; dfs(1,0,n); cout<<total; return 0; }
-
0
一道只需要三重循环枚举就能AC的题目。 第一重循环枚举购买奖品 的个数。因为只有 元钱,而奖品 的单价是 元所以至多能买到 个奖品 ,同理,至多能买到 个奖品 , 个奖品 。 最后只需要用三个循环变量 , , 来枚举三个奖品个分别要买多少个就行了。注意:最后还要条件判断一下此方案是否满足题目要求,即这些奖品总数要超过 个,并且每种奖品至少买一个,这 元钱必须全部花完,如满足就将方案数加 。
代码1:
#include <cstdio>//1.0版代码 using namespace std; int n,a,b,ans; int main() { scanf("%d%d%d",&n,&a,&b);//可替换为cin>>n>>a>>b; for(int i=1;i<=n/a;i++)//枚举购买奖品A个数 for(int j=1;j<=n/b;j++)//枚举购买奖品B个数 for(int k=1;k<=n;k++)//枚举购买奖品C个数 if(i*a+j*b+k==n&&i+j+k>30)//判断是否满足题意 ans++;//如满足,方案数加1 printf("%d\n",ans);//输出,可替换为cout<<ans<<endl; return 0; }
仔细观察,可以发现,这个程序的时间复杂度是可以被优化的。设买了 个奖品 , 个奖品 , 个奖品 , 当买完奖品 后,只剩下 元钱去买奖品 和奖品 。我们此时会发现,剩下的钱至多能买 个奖品 。同样的,买完奖品 和奖品 后,只会剩下 元钱去买奖品 ,剩下的钱至多能买 个奖品 。所以,循环变量 只需循环到 ,循环变量 只需循环到 。
代码2:
#include <cstdio>//2.0版代码 using namespace std; int n,a,b,ans; int main() { scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n/a;i++)//枚举购买奖品A个数 for(int j=1;j<=(n-i*a)/b;j++)//枚举购买奖品B个数,优化后的代码 for(int k=1;k<=(n-i*a-j*b);k++)//枚举购买奖品C个数,优化后的代码 if(i*a+j*b+k==n&&i+j+k>30) ans++; printf("%d\n",ans); return 0; }
其实,这个代码还可以再次被优化。因为题目中已经明确地指出了“这 元钱必须全部花完”,所以实际上第三重循环可以被省去。
代码3:
#include <cstdio>//3.0版代码 using namespace std; int n,a,b,ans; int main() { scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n/a;i++)//枚举购买奖品A个数 for(int j=1;j<=(n-i*a)/b;j++)//枚举购买奖品B个数 { int k=n-i*a-j*b;//购买奖品C的个数 if(k>0&&i+j+k>30)//这里要条件判断一下购买奖品C的个数是否不为0 ans++; } printf("%d\n",ans); return 0; }
-
0
看到同学们的题解都写的不错,不过题解的代码格式还得注意一下,可以去讨论区看一下我写的关于题解。
这个题的话就是一个很经典的枚举问题,不过要注意数据范围,确实是有些没必要的循环就不要进行了~
代码如下:
#include <bits/stdc++.h> using namespace std; int n, a, b, c, k, sum; int main() { cin >> n >> a >> b; for (int i = 1; i <= n / a; i++) { for (int j = 1; j <= n / b; j++) { k = n - i * a - j * b; if ((i + j + k > 30) && (k >= 1)) { sum++; } } } cout << sum; return 0; }
- 1
信息
- ID
- 1224
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 253
- 已通过
- 109
- 上传者