目录
1、牛牛的快递
1.1题目
1.2 思路
1.3 代码实现
1.4 拓展 ceil函数(代码实现)
2、最小花费爬楼梯
2.1 题目
2.2 思路
2.3 代码实现
2.4 其他写法
3、数组中两个字符串的最小距离
3.1 题目
3.2 思路
3.3 代码实现
0x3f3f3f3f是什么
1、牛牛的快递
1.1题目
1.2 思路
通过题目我们知道了,会出现以下四种情况:
(1) 、快递不加急且小于20KG;
(2) 、 快递加急且小于20KG;
(3) 、快递不加急且大于20KG;
(4) 、 快递加急且大于20KG;
当快递大于20KG时,1元/KG,且不足1KG按1元计算,这就是一个向上取整的过程,理清思路,接下来就是代码实现。
1.3 代码实现
#include <iostream>
using namespace std;int main()
{float a;char b;int res = 0;cin >> a >> b;if (a > 1) { int flag = 0;while (a > 0) //记录超过1kg的部分是多少钱{if (a - 1 > 0)flag++;a--;}res = 20 + flag;} else //如果小于1kg就是20元 res = 20;//判断是否加急if (b == 'y') res += 5;cout << res << endl;return 0;
}
1.4 拓展 ceil函数(代码实现)
celi函数用于向上取整,floor函数用于线下去取整
#include <iostream>
#include <cmath>
using namespace std;
int main()
{double a;char b;cin >> a >> b;int ret = 0;if(a <= 1){ret += 20;}else{ret += 20;a -= 1;ret += ceil(a);}if(b == 'y') ret += 5;cout << ret << endl;return 0;
}
2、最小花费爬楼梯
2.1 题目
2.2 思路
这是一道典型的动态规划题目,动态规划就会涉及状态表示和状态转移方程。
cost[i]表示在第 i 个台阶向上爬时,支付所在 i 位置的费用,所以我们只需要支付爬之后 i 位置的钱即可。接下来分析状态表示和状态转移方程。
定义一个 dp[i] 数组,表示到达 i 位置的最小花费;
我们每次可以爬一阶或两阶楼梯,到达是不需要花费的,所以我们假设要到达 i 位置,实际花费的时 dp[i-1] 或 dp[i-2] 的最小费用,依次类推,得出状态转移方程
注意:我们填表时,要用到 i-1,i-2 位置的值,所以要把dp[0] 和 dp[1] 初始化一下,我们可以选择从0或者1位置起跳,那么第一个台阶就是 dp[0] = 0;第2个台阶就是 dp[1] = 0;因为要到数组的下一个位置才算到达终点,所以要到 n 的位置,所以我们要返回 dp[n] ;理清思路,接下来就是代码实现。
2.3 代码实现
#include <iostream>
using namespace std;const int N = 1e5 + 10;
int cost[N];
int dp[N];int main() {int n;cin >> n;for (int i = 0; i < n; i++) cin >> cost[i];//从第三个楼梯开始计费for (int i = 2; i <= n; i++) {dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}cout << dp[n] << endl;return 0;
}
2.4 其他写法
#include <iostream>
#include<vector>
using namespace std;int main()
{int n;cin >> n;vector<int> cost(n);for(int i = 0;i<=n;i++)cin >> cost[i];if(n == 0)return 0;else if(n==1)return cost[0];else if(n==2)cout<< min(cost[0],cost[1]);else{vector<int> res(n);res[0]= cost[0];res[1]= cost[1];for(int i = 2; i< n; i++)res[i]= cost[i] + min(res[i-1],res[i-2]);cout << min(res[n-1],res[n-2]) << endl;}return 0;
}
3、数组中两个字符串的最小距离
3.1 题目
3.2 思路
题目要求在第一个字符串strs中找到str1和str2下标之间的最小距离,如果strs中不存在str1或str2,则输出-1,注意以下几点:
(1)、strs中存在str1或str2但其中一个或两个为空时,输出-1;
(2)、strs中可能存在多个str1、str2,求出其中最小距离即可;
一)蛮力法,用两层for循环遍历加一个判断,找到匹配的下标,定义一个中间变量更新最小距离即可,但时间复杂度为O(n^2),超时了,那么优化一下;
用几个变量标记一下前区的最优解,这里定义两个变量prev1,prev2记录str1和str2的下标,变量到i位置时,仅需看看离他最近位置的匹配的下标,仅需向左边找即可,因为右边走到后面会进行寻找。
变量strs,找到str1或str2时看看之前是否有str1或str2,有则更新最小距离,否则更新prev1或prev2,继续遍历,理清思路,接下来就是代码实现。
3.3 代码实现
将prev1、2,初始化为-1,-1是无效下标,因为刚开始并未有str1或str2,
#include <iostream>
#include <string>
using namespace std;
int main() {int n;string s1, s2;string s;cin >> n;cin >> s1 >> s2;int prev1 = -1, prev2 = -1, ret = 0x3f3f3f3f;for (int i = 0; i < n; i++) {cin >> s;if (s == s1) { // 去前面找最近的 s2if (prev2 != -1) {ret = min(ret, i - prev2);}prev1 = i;} else if (s == s2) { // 去前面找 s1if (prev1 != -1) {ret = min(ret, i - prev1);}prev2 = i;}}if (ret == 0x3f3f3f3f) cout << -1 << endl;else cout << ret << endl;return 0;
}
0x3f3f3f3f是什么
0x3f3f3f3f是在编程中一个常见的使用技巧,这是一个十六进制的数,转换为十进制侯大约是1061109567,这个值比INT_MAX(2147483647)要小,但足够大,可以用作一个初始的“无穷大”值。
为什么使用0x3f3f3f3f 而不是 INT_MAX
为了避免溢出,INT_MAX有时候与一个正式相加,可能会溢出变成负数,因为INT_MAX是int类型能表示的最大值,但0x3f3f3f3f 比较小,就不太可能溢出。
但是在大多数情况下使用INT_MAX是更安全,更清晰的选择.
本篇完,下篇见!如有问题,欢迎指出!