一、添加逗号
题目解析

这道题,给我们一个很大的数
N
,要求我们给N
每三位加一个,
;这里要注意:这个数很大 ,我们要用
long long
类型;
算法思路
这道题可以说非常简单了,先来看最直接的方法:
- 我们可以将一个数从个位开始,一位一位的取出来;
- 所以我们就可以从个位开始,一位一位的取出来,每取出来
3
位就加上,
- 这里我们取出来的每一位要放到字符串
ret
中;进行上述操作之后,需要进行去掉尾部的,
操作- 完成上述所以操作,此时我们得到的字符串是倒序的,我们就要进行逆序再输出。
我们思考一下,这个数特别大,我们是不是可以按照字符串string
的方式进行输入,再对字符串进行相关操作来完成加,
按照字符串进行输入,然后
从前/后
开始进行遍历,注意应该在哪个字符的后面加,
即可

- 我们仔细观察上图,我们需要在下标
2
和5
位置的后面加,
- 细心的朋友可能已经看出来了,当
(n - i - 1)%3 == 0
时,我们就要进行在后面加,
的操作;- 但是此时,下标
i
等于n-1
时是不需要进行+,
的,所以要进行一下单独判断的
代码实现
方法一:
cpp
#include <iostream>
using namespace std;
int main() {
long long n;
cin>>n;
long long x = n;
string str;
int i =0;
while(x)
{
str+=(x%10 +'0');
i++;
if(i%3==0)
str+=',';
x/=10;
}
while(str.size()>1 && str.back() == ',')
str.pop_back();
string ret;
for(int i = str.size()-1;i>=0;i--)
{
ret.push_back(str[i]);
}
cout<<ret<<endl;
return 0;
}
方法二:
cpp
#include <iostream>
using namespace std;
int main() {
string str;
cin>>str;
string ret;
int n = str.size();
for(int i=0;i<str.size();i++)
{
ret +=str[i];
if((n-i-1)%3==0 && i!=n-1)
ret+=',';
}
cout<<ret<<endl;
return 0;
}
二、跳台阶
题目解析

题目说,有一只青蛙,每次可以向上跳
一级或者两级
,让我们求青蛙跳上n
级台阶一共有多少中方法;
算法思路
这是一道简单的dp
,动态规划问题;这里简单分析一下
- n = 2:到第2级台阶,可以从第一级台阶跳过来;也可以从第0级直接跳两级。有两种跳法。
- n = 3 :我们可以从 第一级台阶跳两级跳过来 ,也可以 从第二级台阶挑一级跳过来 ;而跳到第一级的方法有一种 ,跳到第二级的方法有两种 ,所以跳到第三级台阶一共有
3
中方法。- 依次类推
所以这里我们就找到了dp
的状态转移方程。
dp[i]
:表示跳到第i
级台阶一共多少种方法- 状态转移方程 :
dp[i] = d[i-1] +dp[i-2]
代码实现
cpp
#include <iostream>
using namespace std;
const int N = 41;
int dp[N];
int main() {
int n;
cin>>n;
dp[1] =1;
dp[2] =2;
for(int i = 3;i<=n;i++)
{
dp[i] = dp[i-1] + dp[i-2];
}
cout<<dp[n]<<endl;
return 0;
}
三、扑克牌顺序
题目解析

这道题,给了我们
五个数
,让我们判断这五个数能否组成顺子
;有一些特殊规则如下:
A
为1
,J
为11
,Q
为12
,K
为13
(A
不能当做14
):有了这一个规则,我们的数据范围是[1 , 13]
;这样如果能组成顺子,这五个数就是连续的。大王
和小王
为0
,可以当做任意牌使用。- 给定的数据中,最多有
4
个0
;也就是说数据一定是合理的。
算法思路
这里先来看第一种思路,也是博主在做这道题时想到的思路:
排序: 这里排序之后数据有序了,方便我们进行遍历操作。
记录
0
的个数: 数组有序之后0
都在最左边,我们先进行记录0
的个数。用
0
的个数减去相邻两个数中间值的个数
: 在遍历的过程中,我们用0
的个数减去相邻两个数中间值的个数
。结果判断: 遍历结束之后,如果
0
的个数是>=0
的就代表我们能够使用0
去补充完缺少的数,就代表可以构成顺子;反之则不能。这里要注意: 当我们遍历过程中,如果遇到两个数相等,就可以直接返回
false
,因为如果存在相同的数那就一定不能构成顺子。
现在来看一下另外一种思路
如果
5
个数能够组成顺子,那么一定满足下面两个条件:
- 一定不存在相同的数
最大数 - 最小数
一定是<=4
的如果那个组成顺子,就比如
4,5,6,7,8
,不存在相同的数,且最大值 - 最小值 = 8 - 4 = 4
。
那我们就可以根据这一点来下手,只要不存在相同的数且最大数 - 最小数
是<=4
的,那么就可以构成顺子。
那这样我们的思路就来了
- 定义一个
hash
数组,来标记出现的每一个数。- 再记录一下最大值和最小值。
这样在输入的过程中,就可以进行相关操作了,遇到已经存在的数就直接返回
false
,并记录最大最小值。
代码实现
方法一:
cpp
class Solution {
public:
bool IsContinuous(vector<int>& numbers) {
int zero = 0;
sort(numbers.begin(), numbers.end());
int i = 0, n = numbers.size();
while (i < n && numbers[i] == 0) {
zero++;
i++;
}
for (; i < n - 1; i++) {
if (numbers[i + 1] == numbers[i]) return false;
zero -= (numbers[i + 1] - numbers[i] - 1);
}
if (zero >= 0)
return true;
else
return false;
}
};
方法二:
cpp
class Solution {
public:
bool hash[14] = {false};
bool IsContinuous(vector<int>& numbers) {
int x = 0;//表示最大值
int y = 14;//表示最小值
for(auto& e:numbers)
{
if(e)
{
if(hash[e])
return false;
hash[e] = true;
x = max(x,e);
y = min(y,e);
}
}
return (x - y)<=4;
}
};
if(hash[e])
return false;
hash[e] = true;
x = max(x,e);
y = min(y,e);
}
}
return (x - y)<=4;
}
};
继续加油!