很震撼啊,上午c++第三题死活没想出来哪里来的最优算法,c无聊翻leetcode找到了
难怪呢,O(N),那是够少的
我是真不会位运算啊orz,但是很有趣,遂记
(另:我讨厌leetcode的输入方式!以及,我看不懂,题解到底,在写些什么)
先是,关于c++的位运算
参考资料 https://blog.csdn.net/SenyeLicone/article/details/52196039
https://www.cnblogs.com/jaszzz/p/12635375.html (这个排版好酷)
离散数学
*运算数据按照二进制按位运算后,会转化为原数据类型
较常用:按位与、或、非、异或(诡异的好用!)
& | ! ^
暂时接触不多:取反(~),左移(<<),右移(>>)
&:
1.清零
可以和0做&运算,直接清零。(为什么不等于0啊)
2.取数中 指定位
取一个数,指定位上为1,其余为0,做&运算
|
将指定位 变为1,和在该位为1的数做|运算
^
好!东!西!
异或运算,在该位相同为0,相异为1
(1)使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。
例:X=10101110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001即可得到。
(2)与0相异或,保留原值 ,X ^ 0000 0000 = 1010 1110。
(3)也是!非常重要!用于下题(及类似题的思路)
判断一个数出现了几次!!!!!!!
请看——
Leetcode136
来我们忽略那个奇怪的输入输出
一般可以的思路(暴力):快排一次,然后每一位和下一位比较,不同即输出
压缩复杂度,也就是经题解说的,位运算(!)
异或运算,每一位相同返回0,不同返回1,那么——
·1.两个相同的数,异或后一定为0;
2.0与任何数异或都为这个数本身
3.异或没有顺序
可以由此想到,题目中所有偶数次 数异或后为0,单数次 数异或后保留,故输出所有位数异或结果,即为单数次数本身!
是不是!超级奇妙!O(N)!好耶!
代码(正在研究陌生的写法中,这份是别人的,研究好后替换)
class Solution { public: int singleNumber(vector<int>& nums) { int x = 0; for (int num : nums) // 1. 遍历 nums 执行异或运算 x ^= num; return x; // 2. 返回出现一次的数字 x } };View Code
暂存于此
矩阵幂
c 作业 2#include<stdio.h> #pragma warning (disable:4996) int main() { int k; scanf("%d", &k);//测试样例个数 for (int t = 1; t <= k; t++) { int M, N; int a[100][100], b[100][100]; int c[100][100]; scanf("%d %d", &M, &N);//矩阵大小,几次幂 for (int i = 0; i < M; i++) for (int j = 0; j < M; j++) { scanf("%d", &a[i][j]); b[i][j] = a[i][j]; c[i][j] = 0; } for (int s = 2; s <= N; s++) { for (int i = 0; i < M; i++) for (int j = 0; j < M; j++) { c[i][j] = 0; } for (int i = 0; i < M; i++) for (int j = 0; j < M; j++) { for (int k = 0; k < M; k++) c[i][j] += a[i][k] * b[k][j]; } for (int i = 0; i < M; i++) for (int j = 0; j < M; j++) { a[i][j] = c[i][j]; } } for (int i = 0; i < M; i++) { for (int j = 0; j < M; j++) { printf("%d ", c[i][j]); } printf("\n"); } printf("\n"); } return 0; }
标签:0000,运算,nums,int,奇妙,异或,翻转 From: https://www.cnblogs.com/Phantomhive/p/17678045.html