链表的合并
题目描述
运行代码
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{ int a[31];
for(int i = 1;i <= 30;i++)
cin>>a[i];
sort(a + 1,a + 1 + 30);
for(int i = 1;i < 30;i++)
cout<<a[i]<<" ";
cout<<a[30]<<endl;
return 0;
}
代码思路
- 定义数组:定义了一个大小为31的整数数组
a
,但实际上我们只使用前30个位置(从a[1]
到a[30]
)。在C++中,数组通常从索引0开始,但这里为了某种原因(可能是题目要求或其他原因),代码从索引1开始。 - 输入数据:使用for循环从标准输入读取30个整数,并将它们存储在数组
a
的索引1到30中。 - 排序数据:使用
std::sort
函数对数组进行排序。注意,这里传递给sort
函数的是数组的起始地址和结束地址(不包括结束地址对应的元素)。 - 输出数据:使用for循环输出排序后的数组元素。但是,这里有一个小错误:循环的条件是
i < 30
,这意味着它会输出索引从1到29的元素,而遗漏了索引为30的元素。 - 输出最后一个元素:在for循环之后,单独输出索引为30的元素。
改进代码
- 数组索引:为了与C++的常规做法保持一致,并避免潜在的错误,最好从索引0开始使用数组。这样,你就不需要为数组分配额外的空间,也不需要记住从哪个索引开始读取或写入数据。
- 输出循环:为了简洁起见,可以将输出索引为30的元素的代码移到for循环中。这样,你就不需要单独处理最后一个元素了。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a[30]; // 直接定义大小为30的数组
for(int i = 0; i < 30; i++) // 从索引0开始读取数据
cin >> a[i];
sort(a, a + 30); // 直接使用数组的起始和结束地址
for(int i = 0; i < 30; i++) // 从索引0开始输出数据
cout << a[i] << " ";
cout << endl; // 在循环后直接输出换行符
return 0;
}
兑换零钱
题目描述
运行代码
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
const int mod=1e9+7;
int a[20]={1,2,5,10,20,50,100,200,500,1000,2000,5000,10000},dp[100010];
int main()
{
dp[0]=1;
for(int i=0;i<13;i++)
for(int j=a[i];j<=100000;j++)
dp[j]=(dp[j]+dp[j-a[i]])%mod;
int N,T;
cin>>T;
while( T-- )
{
cin>>N;
cout<<dp[N]<<endl;
}
return 0;
}
代码思路
- 初始化
dp[0]
为1,因为凑成面额0只有一种方式(即不使用任何硬币)。 - 使用两个嵌套的循环来计算
dp
数组的其他元素。外层循环遍历硬币数组a
,内层循环遍历从当前硬币面额到100000的所有可能面额。对于每个面额j
,我们都检查是否可以使用当前硬币a[i]
来凑成它。如果可以(即j >= a[i]
),则dp[j]
的值是原来的值加上dp[j-a[i]]
(即不使用当前硬币和使用当前硬币的凑法数之和)。 - 最后,程序读取测试用例数量
T
,然后对每个测试用例读取一个整数N
,并输出dp[N]
,即凑成面额N
的方法数。
改进建议
- 避免使用
<bits/stdc++.h>
:这个头文件虽然包含了几乎所有标准库,但它不是标准C++的一部分,而且会增加编译时间。建议只包含你需要的头文件。 - 数组大小:虽然这里定义
dp
数组的大小为100010是足够的,但如果你想要一个更通用的解决方案,你可以根据输入的最大可能值来动态分配这个数组的大小。 - 输入验证:虽然在这个问题中可能不需要,但在实际应用中,验证输入的有效性(例如,确保
N
是非负的)是一个好习惯。 - 注释:添加注释来解释代码的每个部分是如何工作的,以及为什么选择这种特定的实现方式,可以帮助其他人(或未来的你)更容易地理解代码。
- 优化:虽然对于这个问题来说,当前的实现已经足够快,但如果你在处理更大的面额或更多的硬币时,你可能需要考虑更高效的算法,如使用背包问题的优化技术。
改进代码
#include <iostream>
#include <vector>
using namespace std;
const int MOD = 1e9 + 7;
const int MAX = 100000;
vector<int> coin = {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000};
// 动态规划表,用于存储凑成不同面额的方法数
vector<int> Amount(MAX + 1, 0);
int main() {
// 初始化凑成面额0的方法数为1
Amount[0] = 1;
// 动态规划计算凑成不同面额的方法数
for (int i = 0; i < coin.size(); i++) {
for (int j = coin[i]; j <= MAX; j++) {
Amount[j] = (Amount[j] + Amount[j - coin[i]]) % MOD;
}
}
int T, N;
cin >> T; // 读取测试用例数量
while (T--) {
cin >> N; // 读取当前测试用例的面额
cout <<Amount[N] << endl; // 输出凑成面额N的方法数
}
return 0;
}