位运算 二进制中1的个数 给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 11 的个数。
输入格式 第一行包含整数 n。
第二行包含 n 个整数,表示整个数列。
输出格式 共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 11 的个数。
数据范围 1≤n≤100000 0≤数列中元素的值≤1e9
输入样例:
输出样例:
个人 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <bits/stdc++.h> using namespace std;int main () { int n;cin>>n; for (int i=0 ;i<n;i++){ int v; cin>>v; int cnt = 0 ; while (v){ cnt += v%2 ; v/=2 ; } printf ("%d " ,cnt); } }
板子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std; int main() { int n; scanf("%d", &n); while (n -- ) { int x, s = 0; scanf("%d", &x); for (int i = x; i; i -= i & -i) s ++ ; printf("%d ", s); } return 0; }
位运算的应用:
查看数字二进制表示的第K位是几?
查看二进制数字中有多少位1
lowbit函数:返回最后一位1。
1 2 3 4 5 6 7 8 9 10 int lowbit (int x) { return x&-x; }
对应得完整代码为
1 2 3 4 5 6 7 8 int checkOne (int x) { int cnt = 0 ; while (x) { x -= lowbit (x); cnt++; } return cnt; }
离散化 区间和 假定有一个无限长的数轴,数轴上每个坐标上的数都是 00。
现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。
接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 <l,r> 之间的所有数的和。
输入格式 第一行包含两个整数 n 和 m。
接下来 n 行,每行包含两个整数 x 和 c。
再接下来 m 行,每行包含两个整数 l 和 r。
输出格式 共 m 行,每行输出一个询问中所求的区间内数字和。
数据范围 −1e9≤x≤1e9, 1≤n,m≤1e5, −1e9≤l≤r≤1e9, −10000≤c≤10000
输入样例: 1 2 3 4 5 6 7 3 3 1 2 3 6 7 5 1 3 4 6 7 8
输出样例:
个人
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <bits/stdc++.h> using namespace std;vector<int >num; vector<pair<int ,int >>allInsert; vector<pair<int ,int >>allQuery; int sumV[300010 ];int find (int x) { int left = 0 ; int right = num.size () - 1 ; while (left <= right){ int mid = (left + right) /2 ; if (num[mid] > x) { right = mid - 1 ; } else if (num[mid] < x) { left = mid + 1 ; } else { return mid + 1 ; } } } int main () { int n,m; cin>>n>>m; for (int i=0 ;i<n;i++){ int a,b; scanf ("%d %d" ,&a,&b); allInsert.push_back ({a,b}); num.push_back (a); } for (int i=0 ;i<m;i++){ int l,r; scanf ("%d %d" ,&l,&r); num.push_back (l); num.push_back (r); allQuery.push_back ({l,r}); } sort (num.begin (), num.end ()); num.erase (unique (num.begin (), num.end ()),num.end ()); for (auto x: allInsert) { int index = find (x.first); sumV[index] += x.second; } for (int i=1 ;i<=num.size ();i++){ sumV[i] += sumV[i-1 ]; } for (auto x: allQuery){ int l = find (x.first); int r = find (x.second); printf ("%d\n" ,sumV[r] - sumV[l-1 ]); } }
区间合并 给定 n 个区间 <l,r>要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:<1,3> 和 <2,6> 可以合并为一个区间 <1,6>。
输入格式 第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。
输出格式 共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围 1≤n≤100000, −1e9≤li≤ri≤1e9
输入样例:
输出样例:
个人代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include<bits/stdc++.h> using namespace std; // 声明了一个自定义的比较类型 bool cmp(pair<int,int>l, pair<int,int> r) { if (l.first == r.first) { return l.second > r.second; } return l.first<r.first; } int main() { int n; cin>>n; vector<pair<int,int>> num; for(int i=0;i<n;i++){ int l,r; cin>>l>>r; num.push_back({l,r}); } sort(num.begin(), num.end(),cmp); int cnt = 0; int right = num[0].second; for(int i=1;i<n;i++){ auto now = num[i]; if (now.first > right) cnt++; right = max(right,now.second); // 此处出现细节错误,忘记更换right的判断 } cout<<cnt + 1<<endl; } /* 5 1 2 2 4 5 6 7 8 7 9 */
板子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <vector> #include <algorithm> using namespace std; typedef pair<int , int > PII; void merge (vector<PII> &segs) { vector<PII> res; sort(segs.begin(), segs.end()); int st = -2e9 , ed = -2e9 ; for (auto seg : segs) if (ed < seg.first) { if (st != -2e9 ) res.push_back({st, ed}); st = seg.first, ed = seg.second; } else ed = max(ed, seg.second); if (st != -2e9 ) res.push_back({st, ed}); segs = res; } int main () { int n; scanf("%d" , &n); vector<PII> segs; for (int i = 0 ; i < n; i ++ ) { int l, r; scanf("%d%d" , &l, &r); segs.push_back({l, r}); } merge(segs); cout << segs.size() << endl; return 0 ; }
1 2 很荣幸能来到青软,在这里我将开始我为期一年半的学习,总的来说这里学习氛围和学校相比更好。在这里我主要进行了一下几方面的学习,因为个人偏向与java后端开发的岗位,所以会选择适当舍弃一些课程。 1.开始了我的算法学习,毫无疑问的是算法是da