補題連接:Hereios
對 \(N\) 進行奇偶判斷,奇數穿 Black
、偶數穿 White
c++
前 \(n\) 項和公式:\(S_n = \frac{n(a_1 + a_n)}{2}\)ui
簡單套公式計算便可。spa
注意點:使用 long long
.net
題意:給 N 組座標,判斷這些座標中,是否存在三個不一樣點處於同一條直線。若是存在,輸出 Yes,不然輸出 No。code
本題是一個數學題,假設咱們有三個點,座標分別爲:點 A 爲 (x1, y1)、點 B 爲 (x2, y2) 和點 C 爲 (x3, y3)。orm
判斷三點共線blog
假設這三個點共線,則排序
這樣咱們能夠變換爲ci
因爲本題數據範圍較小能夠暴力遍歷
#include <bits/stdc++.h> using namespace std; typedef struct _POS { int x; int y; } POS; const int MAXN = 1e2 + 4; POS arr[MAXN]; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> arr[i].x >> arr[i].y; //暴力枚舉 for (int i = 1; i <= n - 2; i++) for (int j = i + 1; j <= n - 1; j++) for (int k = j + 1; k <= n; k++) if ((arr[k].x - arr[i].x) * (arr[j].y - arr[i].y) == (arr[j].x - arr[i].x) * (arr[k].y - arr[i].y)) { cout << "Yes\n"; return 0; } cout << "No\n"; return 0; }
核心在於 整數是否能被 \(8\) 整除都取決於後三位
題意:給定一個字符串(由 1
~ 9
構成),請問是否能經過重排序來使這個字符串整數爲 \(8\) 的倍數。
思路:
在數學問題上,有如下是成立的
一般,爲 \(2^k\) 的倍數等效於使最後 \(k\) 個數字爲 \(2^k\) 的倍數。 讓我簡要地展現8的倍數的狀況。
\(1000 = 2^3 \times 5^3\)
注意:\(1000\) 可被 \(8\) 整除,所以,對於任何整數 \(n\) ,可令 \(q\) 爲 \(n\) 除以 \(1000\) 的商,\(r\) 爲餘數
即:\(n = 1000q + r\)
故此,\(r\) 剛好爲 \(n\) 的最後三位數。
此時:\(n \equiv 1000q + r \equiv (\ mod\ 8)\)
如今回到原來的問題上;
關於 S 是否爲 8 的倍數,咱們進行分狀況討論
\(|S| \le 3\) 的狀況咱們能夠直接全排列
\(|S| > 4\) 的狀況咱們能夠考慮以下。
考慮 \(8\) 的倍數的全部可能的後三位數字。 肯定是否能夠從 \(S\) 知足它們中的任何一個。
實際上 \(1000\) 之內的 \(8\) 的倍數僅 124個,因此運行速度會很快
#incwlude <bits/stdc++.h> using namespace std; using ll = long long; bool solve(string S) { if (S.size() <= 5) { sort(S.begin(), S.end()); do { int val = 0; for (auto c : S) val = val * 10 + (int)(c - '0'); if (val % 8 == 0) return true; } while (next_permutation(S.begin(), S.end())); return false; } vector<int> all(10, 0); for (const auto c : S) all[c - '0']++; for (int i = 0; i < 1000; i += 8) { vector<int> num(10, 0); int i2 = i; for (int iter = 0; iter < 3; ++iter) { num[i2 % 10]++; i2 /= 10; } bool ok = true; for (int v = 0; v < 10; ++v) if (num[v] > all[v]) ok = false; if (ok) return true; } return false; } int main() { ios_base::sync_with_stdio(false), cin.tie(0); string s; cin >> s; cout << (solve(s) ? "Yes" : "No"); return 0; }
題意:
給出 N個整數,且N爲奇數,回答M個回答
數據範圍:
思路:
https://blog.csdn.net/justidle/article/details/109509824
#include <bits/stdc++.h> using namespace std; using ll = long long; template <class T> void chmax(T &a, T b) { if (a < b) a = b; } template <class T> void chmin(T &a, T b) { if (a > b) a = b; } const ll inf = 1LL << 60; int main() { ios_base::sync_with_stdio(false), cin.tie(0); int N, M; cin >> N >> M; vector<ll> X(N), W(M); for (ll &x : X) cin >> x; for (ll &x : W) cin >> x; sort(X.begin(), X.end()); vector<ll> left(N + 1, 0), right(N + 1, 0); for (int i = 2; i < N; i += 2) { left[i] = left[i - 2] + X[i - 1] - X[i - 2]; right[i] = right[i - 2] + X[N - i + 1] - X[N - i]; } ll ans = inf; for (auto w : W) { int i = lower_bound(X.begin(), X.end(), w) - X.begin(); if (i % 2 == 0) chmin(ans, left[i] + right[N - i - 1] + X[i] - w); else chmin(ans, left[i - 1] + right[N - i] + w - X[i - 1]); } cout << ans << '\n'; return 0; }
有一個 \(200×2×10^9\) 的網格,其中橫座標區間爲 [−100,100]
,縱座標區間爲 \([−10^9,10^9]\)。平面上有若干個點。
你有一個圓,最開始在 \((0,−10^9)\),詢問圓半徑最大是多少使得它能夠在不接觸點的狀況下圓心到達 \((0,10^9)\)。
思路:
二分圓的直徑,若是兩個點之間的距離小於直徑,那麼顯然圓無法從這兩個點之間通過。注意要把直線 \(x=100\) 和\(x=−100\) 也看作一個點。
那麼若是連完線以後把直線 \(x=100\) 和 \(x=−100\) 聯通,那麼至關於存在若干連線將左右兩邊隔開,這樣圓就沒法過去。不然能夠到達。
用並查集維護便可。
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; using Edge = pair<double, pii>; struct UnionFind { vector<int> par; UnionFind(int n) : par(n, -1) {} void init(int n) { par.assign(n, -1); } int find(int x) { return par[x] < 0 ? x : par[x] = find(par[x]); } bool issame(int x, int y) { return find(x) == find(y); } void merge(int x, int y) { x = find(x), y = find(y); if (x != y) { if (par[x] > par[y]) swap(x, y); par[x] += par[y]; par[y] = x; } } }; int main() { ios_base::sync_with_stdio(false), cin.tie(0); int N; cin >> N; vector<double> x(N), y(N); for (int i = 0; i < N; ++i) cin >> x[i] >> y[i]; auto calc = [&](int i, int j) -> double { return sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])); }; vector<Edge> edges; int s = N, t = N + 1; for (int i = 0; i < N; ++i) { edges.push_back(Edge(100.0 - y[i], pii(s, i))); edges.push_back(Edge(100.0 + y[i], pii(t, i))); for (int j = i + 1; j < N; ++j) { edges.push_back(Edge(calc(i, j), pii(i, j))); } } sort(edges.begin(), edges.end()); UnionFind uf(N + 2); double res = 0.0; for (auto e : edges) { uf.merge(e.second.first, e.second.second); if (uf.issame(s, t)) { res = e.first / 2; break; } } cout << fixed << setprecision(10) << res << endl; return 0; }