加法
像这一类题目很多笔试中都有可能考,例如不使用*运算符实现乘法,这道题目,不使用运算符实现加法,当不能使用运算符时,一般都是位运算,这时候就要考虑如何使用。实际上加法就是两个数求和后当前位的数据,加上进位的数据。例如175 + 186,加之后当前为的数据为251(1 + 1, 7 + 8 - 10, 5 + 6 - 10),进位的数据为110(十位进一次到百位,个位进一次到十位),251 + 110 = 361
下面用一个例子说明:随便两个二进制数字。
1011000101
0111001101
加之后当前位的数据为
1100001000
加之后进位的数据为
0110001010
继续将这两个数相加
当前位
1010000010
进位
1000010000
继续加直到当前位或者进位为0
通过上述我们可以发现,当前位可以用异或(a ^ b) 来表示,进位可以用与运算后进一位((a & b) << 1)来表示,持续加的过程可以用递归实现终止条件为某一个数为0。
示例代码:
class UnusualAdd {
public:
int addAB(int A, int B) {
//终止条件
if (A == 0)
return B;
if (B == 0)
return A;
//当前位
int a = A ^ B;
//进位
int b = (A & B) << 1;
//递归
return addAB(a, b);
}
};
走方格的方案数
两种思路:
1.高中学过排列组合就知道这题可以套公式:结果为((n + m) * (n + m - 1) * … * (n)) / (n) * (n - 1) * … * 1)) 或 ((n + m) * (n + m - 1) * … * (m)) / (m) * (m - 1) * … * 1))
示例代码:
#include <iostream>
using namespace std;
//累乘
int Fac(int m, int n = 0){
int pro = 1;
if (n != 0){
for (int i = m, j = 1; j <= n; ++j){
pro *= i;
--i;
}
}
else{
for (int i = 1; i <= m; ++i)
pro *= i;
}
return pro;
}
int main(){
int n, m;
cin >> n >> m;
cout << ((Fac(m + n, n) / Fac(n))) << endl;;
return 0;
}
2.递归思想
01 – 02 – 03 – 04
| | | |
05 – 06 – 07 – 08
| | | |
09 – 10 – 11 – 12
我们看到从01到05只有一条路,从01到02也是只有一条路,所以01-12可以转换为(05 – 12) + (02 – 12),终止条件为(12 – 12)
当到边界的时候,例如09, 08,11这样的路径数为1,不用递归
示例代码:
#include <iostream>
using namespace std;
int Path(int n, int m){
//非边
if (n > 1 && m > 1){
return Path(n - 1, m) + Path(n, m - 1);
}
//边上
else if (n == 1 && m >= 1)
return 1;
else if (n >= 1 && m == 1)
return 1;
//终点处
else
return 0;
}
int main(){
int n, m;
cin >> n >> m;
//我们的思想是按照点来看,题目给的是格子数,所以参数要加一
cout << Path(n + 1, m + 1) << endl;
return 0;
}