voidquick_sort(int l, int r){ if (l >= r) return; int i = l - 1, j = r + 1, x = a[(l + r) >> 1]; while (i < j) { while (a[++i] < x) {}; // 没有 i < j while (a[--j] > x) {}; if (i < j) swap(a[i], a[j]); } quick_sort(l, j); // j, 而非i quick_sort(j + 1, r); }
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); quick_sort(0, n - 1); for (int i = 0; i < n; i++) printf("%d ", a[i]); return0; }
intquick_choose(int l, int r, int k){ if (l >= r) return a[l]; int i = l - 1, j = r + 1, mid = (l + r) >> 1, pivot = a[mid]; while (i < j) { while (a[++i] < pivot) {}; while (a[--j] > pivot) {}; if (i < j) swap(a[i], a[j]); } if (k <= j - l + 1) returnquick_choose(l, j, k); // j, 而非mid returnquick_choose(j + 1, r, k - (j - l + 1)); }
intmain(){ int n, k; scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &a[i]); printf("%d\n", quick_choose(0, n - 1, k)); return0; }
voidmerge(int l, int r){ if (l >= r) return; // 终止条件, 否则报TLE int mid = (l + r) >> 1; merge(l, mid); merge(mid + 1, r); int i = l, j = mid + 1, k = 0; while (i <= mid && j <= r) { if (a[i] <= a[j]) { tmp[k++] = a[i++]; } else { tmp[k++] = a[j++]; } } while (i <= mid) tmp[k++] = a[i++]; while (j <= r) tmp[k++] = a[j++]; for (int i = l, j = 0; i <= r; i++, j++) a[i] = tmp[j]; // <= }
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); merge(0, n - 1); for (int i = 0; i < n; i++) printf("%d ", a[i]); printf("\n"); return0; }
intmain(){ int n, q; scanf("%d%d", &n, &q); for (int i = 0; i < n; i++) scanf("%d", &a[i]); while (q--) { int k; scanf("%d", &k); int l = 0, r = n - 1; while (l < r) { int mid = (l + r) >> 1; if (a[mid] >= k) { r = mid; } else { l = mid + 1; } } if (a[l] != k) { printf("-1 -1\n"); } else { printf("%d ", l); l = 0, r = n - 1; while (l < r) { int mid = (l + r + 1) >> 1; if (a[mid] <= k) { l = mid; } else { r = mid - 1; } } printf("%d\n", l); } } return0; }
vector<int> add(vector<int> &A, vector<int> &B){ if (A.size() < B.size()) returnadd(B, A); vector<int> C; int t = 0; for (int i = 0; i < A.size(); i++) { t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t) C.push_back(t); return C; }
intmain(){ string a, b; cin >> a >> b; // a = "12345" vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // A = [5, 4, 3, 2, 1] for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); vector<int> C = add(A, B); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); printf("\n"); return0; }
boolcmp(vector<int> &A, vector<int> &B){ if (A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] > B[i]; } returntrue; }
vector<int> sub(vector<int> &A, vector<int> &B){ vector<int> C; int t = 0; for (int i = 0; i < A.size(); i++) { // 从低到高 t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); t = (t < 0) ? 1: 0; } while (C.size() > 1 && C.back() == 0) C.pop_back(); // >1, 而非>0 return C; }
intmain(){ string a, b; cin >> a >> b; vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); vector<int> C; if (cmp(A, B)) { C = sub(A, B); } else { printf("-"); C = sub(B, A); } for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); return0; }
vector<int> mul(vector<int> &A, int b){ vector<int> C; int t = 0; for (int i = 0; i < A.size(); i++) { t += A[i] * b; C.push_back(t % 10); t /= 10; } if (t) C.push_back(t); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; }
intmain(){ string a; int b; cin >> a >> b; vector<int> A; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); vector<int> C = mul(A, b); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); return0; }
vector<int> mul(vector<int> &A, vector<int> &B){ vector<int> C(A.size() + B.size() + 1, 0); // 初始化为0 for (int i = 0; i < A.size(); i++) { for (int j = 0; j < B.size(); j++) { C[i + j] += A[i] * B[j]; // +=, 而非= } } int t = 0; for (int i = 0; i < C.size(); i++) { t += C[i]; C[i] = t % 10; t /= 10; } if (t) C.push_back(t); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; }
intmain(){ string a, b; cin >> a >> b; vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); auto C = mul(A, B); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); return0; }
vector<int> div(vector<int> &A, int b, int &r){ vector<int> C; for (int i = A.size() - 1; i >= 0; i--) { // 和+ - *不一样 r = 10 * r + A[i]; C.push_back(r / b); r %= b; } reverse(C.begin(), C.end()); // 让数字低位回到数组低位 while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; }
intmain(){ string a; int b; cin >> a >> b; vector<int> A; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); int r = 0; auto C = div(A, b, r); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); printf("\n%d\n", r); return0; }
voidinsert(int l, int r, int c){ b[l] += c; b[r + 1] -= c; }
intmain(){ int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); insert(i, i, a[i]); } while (m--) { int l, r, c; scanf("%d%d%d", &l, &r, &c); insert(l, r, c); } for (int i = 1; i <= n; i++) { b[i] += b[i - 1]; printf("%d ", b[i]); } return0; }
intmain(){ int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); unordered_map<int, int> hash; int res = 0; for (int i = 0, j = 0; j < n; j++) { hash[a[j]]++; while (i < j && hash[a[j]] > 1) { hash[a[i]]--; i++; } res = max(res, j - i + 1); } printf("%d\n", res); return0; }
队列等价
双指针算法 和 双向队列 是等价的,但是使用 双指针 能灵活高效。
1 2 3 4 5 6 7 8 9 10 11
queue<int> q; for (int i = 0; i < n; i++) { // 不能for (auto x: a) int x = a[i]; q.push(x); hash[x]++; while (q.size() && hash[q.back()] > 1) { hash[q.front()]--; q.pop(); } res = max(res, (int)q.size()); // 得转int }
intmain(){ int n, m, x; scanf("%d%d%d", &n, &m, &x); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < m; i++) scanf("%d", &b[i]); for (int i = 0, j = m - 1; i < n; i++) { while (a[i] + b[j] > x) j--; if (a[i] + b[j] == x) { printf("%d %d\n", i, j); break; } } return0; }
intmain(){ int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < m; i++) scanf("%d", &b[i]); int i = 0, j = 0; while (i < n && j < m) { if (a[i] == b[j]) i++; j++; } if (i == n) { // 看短的 printf("Yes\n"); } else { printf("No\n"); } return0; }
题型: lowbit(x)返回x的最后一位1, 比如lowbit(20)=lowbit(10100_2)=100
方法: x & -x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include<iostream>
usingnamespace std;
intmain(){ int n; scanf("%d", &n); while (n--) { int x; scanf("%d", &x); int res = 0; while (x) { x -= x & -x; res++; } printf("%d ", res); } return0; }