由于被很多公司的笔试编程题虐了,才想着要做做算法题了。自己的基础看来太薄弱了些。因此决定先从赛码网的基本算法题开始做起。这里想记录一下赛码网里面题的情况。
由于基础薄弱,就先从两星的题开始做起。每日两道。
第一题:上台阶
这道题看起来比较简单,我们可以从第一级楼梯开始分析。当楼梯只有一级时,有0种走法;当有2级时,有1种走法;有3级时,有2种走法。当有4级时,我们可以想到先从一级跳到第二级,然后二级到四级的情况就变成有3级楼梯时的走法了,这时候有2种走法到四级,同理,如果先从一级跳到第三级后,就和有2级楼梯时一样,因此4级楼梯有2+1种。后面的情况是一样的,如5级楼梯的就是4级的走法加3级的走法。因此可以写出递归式:
f(m)=⎧⎩⎨⎪⎪⎪⎪0 1 2 f(m−1)+f(m−2) (m=1) (m=2) (m=3) (m>3)
所以呢,就是完成这个递归。代码如下:
#include <iostream>
using namespace std;
int f(int m){
if (1 == m) {
return 0;
}
else if(2 == m){
return 1;
}
else if(3 == m){
return 2;
}
else{
return f(m-1)+f(m-2);
}
}
int main()
{
int n;
cin>>n;
int a[n];
for (int i = 0; i < n; i++) {
cin>>a[i];
cout<<f(a[i])<<endl;
}
return 0;
}
第二题:将功赎过
本题的内容就是给定了十进制数的范围,求这个范围中有多少个数的二进制表示中有m个1。
看到这道题,我想到的是在《编程之美》那本书中看到过求一个数二进制表示中有多少个1的问题。因此这里也是先写出获取二进制中有多少个1的函数。接下来就比较简单了,遍历l~r范围中的数,看看有多少个数的二进制1的个数为m。
代码如下:
#include <iostream>
using namespace std;
//返回n转换为二进制后1的个数
int CountOne(int n){
int num = 0;
while(n){
n &= (n - 1);
num++;
}
return num;
}
int getCount(int l,int r,int m){
int m_num = 0;
while (l<=r) {
if (m == CountOne(l)) {
m_num++;
}
l++;
}
if (0 == m_num) {
return -1;
}
return m_num;
}
int main(int argc, const char * argv[]) {
int l,r,m;
cin>>l>>r>>m;
cout<<getCount(l,r,m)<<endl;
return 0;
}