1.
在计算机中,负数是用二进制补码存储的,补码是在正数取反后再加1组成的
所以通过补码我们就可以-1,取反后得到原码,再换10进制得相反数。
补码的作用:因为负数是用补码存储的,所以我们与原码也就是负数的相反数相加,正好是0,所以计算机不需要发明减法器,只需要有加法器。
位运算:
1.&按位与,只有有两个1的时候才为1,其余为0
作用:可以判断一个数的奇偶性。例如:n&1如果为0说明是偶数,如果为1说明是奇数(奇数最后一位二进制位是1,因为是1*2^0才有了1)
2.|按位或 有一个1就为1,其余为0(两个1也是1).
3.<<左移运算,可以计算2的整数指数幂,如1<<n,为2^n
4.>>右移运算,可以将原数往右移动几个二进制位n<<1,等价于n/=2。
5.按位异或^,相同为1,不同为0
作用:可以判断某几个数是不是原数组的子集。
6.~按位取反,实现0变1,1变0操作。可以用来求集合的补集
这个题可以算周期,通过算天数%7得到。1999-2017有18年,其中有2000,2004,2008,2012,2016五个闰年,也就是说(365*18+5)%7可以运用同余性质,分别计算365*18%7,6%7
同理,也可以计算365%7,18%7的值,365%7=1,18%7=4,5%7=5;(5+4)%7=2;所以星期日往前数两天就是周五。
3.
分步,乘法原理。
选两门C(4,2),选两个三门,C(4,3),C(4,3)等价于C(4,1)因为选三个的组合就等于是那一个不选的组合所以是6*4*4=96.
4.
一棵树有n-1条边,所以m条减去需要的,就是删掉的
5.
6.
首先来看看什么叫子串:子串就是包含空串和原串,且具有原串顺序的字符串。
可以分类讨论,从子串长度分析
1:9
2:8
3:7
4:6
5:5
6:4
7:3
8:2
9:1
最后不要忘了空串。
对于十进制小数转二进制小数,乘2取整顺序链接即可,答案为1101.011
7.
我们可以算出来四个人都不在同一月份的概率,之后用1-
我们算出这个概率C(12,4)/12^4,之后用1-即可。
1.
#include <iostream>
using namespace std;
int g(int m, int n, int x) {
int ans=0;
int i;
if(n == 1)
return 1;
for(i = x; i <= m / n; i++)
ans += g(m - i, n - 1, i);
return ans;
}
int main()
{
int t, m, n;
scanf("%d%d", &m, &n);
printf("%d", g(m, n, 0));
return 0;
}
方法:
1.直接模拟。
2.想想代码功能:因为最后递归的结果都是1,1,1,1…………所以我们不可能可以发现,他是关于排列的问题,即从m里挑出n个无序排列。
2.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string ch;
int a[200];
int b[200];
int n, i, t, res;
cin >> ch;
n = ch.length();
for(i = 0; i < 200; i++) b[i] = 0;
for(i = 1; i <= n ; i++) {
a[i] = ch[i-1] - '0';
b[i] = b[i-1] + a[i];
}
res = b[n];
t = 0;
for(i = n; i > 0; i--) {
if(a[i] == 0) t++;
if(b[i-1] + t < res) res = b[i-1] + t;
}
cout << res << endl;
return 0;
}
先输入,之后转成int,b数组保存的是1-i的前缀和。先让result等于1-n的和,由输入样例,我们可以变相将b数组理解为,1-i中1的数量。之后一个for循环,从n开始,用t计数0的数量,下面result是要打擂台求最小值,这里求得最小值是从i-n中0的数量再加上b[i-1]中1的数量的最小值,最后经过一顿毒瘤模拟即可求出答案
3.
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
int x = 1;
int y = 1;
int dx = 1;
int dy = 1;
int cnt = 0;
while(cnt != 2) {
cnt = 0;
x = x + dx;
y = y + dy;
if(x == 1 || x == n) {
++cnt;
dx = -dx;
}
if(y == 1 || y == m) {
++cnt;
dy = -dy;
}
}
cout << x << " " << y << endl;
return 0 ;
}
我们可以看出,n,m是矩阵的长和宽,dx,dy是偏移量,while循环结束的条件是cnt!=2,但是cnt每次都会为0,所以我们想要让while循环结束,就要同时满足两个if分支当等于1,或等于n(m)的时候,就会往反方向走看第一个样例4,3,我们发现他们的周期是不一样的,当他们刚好到达1或n(m)就是[n-1,m-1],为什么是n-1呢?因为x,y是从1开始的。也就是求2,3的最小公倍数,然后我们再算出来走了这么多时,x,y的值即可。
快速幂是倍增的思想,他能在O(log n)的时间复杂度下完成a^n%m的操作。首先要将result初始化成1,因为下面要做乘法,p!=0,我们要取他的二进制位,如果为1,是需要,如果为0,则不需要乘方。我们也可以用p&1来判断,这样直接就可以result=x*x%m,然后x=x*x%m。