题目描述:给定正整数\(n\),判断式子\(2^n > n^2\)是否成立。
思路:显然只有当n = 2 , 3 , 4
时不成立
时间复杂度:\(O(1)\)
参考代码:
void solve() { int n; cin >> n; if (n != 2 && n != 3 && n != 4) cout << "Yes\n"; else cout << "No\n"; return; }
题目描述:给定一块披萨,然后给你一个数组\(A\),每次你需要转动\(a_i\)角度之后,在12
点钟方向切一刀。问最终所有扇形中角度的最大值。
思路:显然让披萨转动和让刀转动等价,我们让刀转动,然后切的时候将对应角度标记为\(1\)。最后再使用双指针求最大值即可。
时间复杂度:\(O(n)\)
参考代码:
void solve() { int n; cin >> n; vector<int>a(n + 1, 0); for (int i = 1; i <= n; ++i) cin >> a[i]; vector<int>deg(361, 0); deg[0] = 1; deg[360] = 1; int cur = 0; for (int i = 1; i <= n; ++i) { cur = (cur + a[i]) % 360; deg[cur] = 1; } int res = 0; int p = 0, q = 1; while (p < 360) { while (deg[q] == 0) ++q; res = max(res, q - p); p = q; q = p + 1; } cout << res << '\n'; return; }
题目描述:定义\(f(x)\)表示与\(x\)位数相同且小于等于\(x\)的数字的个数,对于给定的\(n\),求\(\sum\limits_{i = 1}^{n}f(i)\)。
思路:根据题意显然将\(n\)按照\(10\)的幂次分段,对于每一段,如果有\(m\)个数字,那么对答案的贡献就是\(\frac{m * (m + 1)}{2}\) 。比如\(10 \sim 99\)就是从\(1 \sim 90\)的累加。
时间复杂度:\(O(log_{10}n)\)
参考代码:
void solve() { long long n; cin >> n; long long res = 0; long long p = 10, q = 1; const int mod = 998244353; while (true) { long long m = min(n , p - 1) - q + 1; m %= mod; res = (res + (m * (m + 1) / 2) % mod) % mod; if (p > n) break; p *= 10; q *= 10; } cout << res << '\n'; return; }
题目描述:对于给定的\(a , s\),是否存在\(x , y\)使得以下条件成立:
x AND y = a
x + y = s
多组数据,对于每组数据若存在输出Yes
,否则输出No
。
思路:比较明显,我们可以先通过第一个约束条件将\(x , y\)的二进制表示中必须为\(1\)的找出来,求和为\(sum\)。若\(sum> s\)则显然没有;否则\(s = s - sum\)。然后对于每一个\(x , y\)没使用的二进制位,贪心的从\(s\)中减去,若最终\(s = 0\)则存在,否则不存在。
时间复杂度:\(O(60T)\)
参考代码:
void solve() { long long a, s; cin >> a >> s; vector<int>cnt(60, 0); long long sum = 0; for (int i = 0; i < 60; ++i) { cnt[i] += (a >> i) & 1; if (cnt[i]) sum += 2ll << i; } if (sum > s) { cout << "No" << '\n'; return; } s -= sum; for (int i = 59; i >= 0; --i) { if (cnt[i]) continue; long long dx = 1ll << i; if (dx <= s) s -= dx; } if (s == 0) cout << "Yes" << '\n'; else cout << "No" << '\n'; return; }
题目描述:给你一个整数\(n\),表示有一个长度为\(n\)的正整数数组,告诉你\(q\)个条件,每个条件的形式为 lr rs
,表示\(\sum\limits_{i = lr}^{rs} a_i\) 。问是否可以通过这些条件知道\(\sum\limits_{i = 1}^{n}a_i\)。若能输出Yes
,否则输出No
。
思路:比较明显的图论题。对于每一个条件,可以根据前缀和的知识,抽象成从\(lr - 1\)到\(rs\)存在一条无向边。我们将条件读入并转化成图后,从\(0\)开始dfs
。若最终能访问到第\(n\)个点,则表示可以求出题目的和式,否则不能。
时间复杂度:\(O(n)\)
参考代码:
void solve() { int n, q; cin >> n >> q; vector<vector<int>>graph(n + 1); int u, v; for (int i = 1; i <= q; ++i) { cin >> u >> v; graph[u - 1].push_back(v); graph[v].push_back(u - 1); } vector<bool>vis(n + 1, false); auto dfs = [&](auto dfs, int u)->void { if (vis[u]) return; vis[u] = true; for (auto v : graph[u]) dfs(dfs, v); return; }; dfs(dfs, 0); if (vis[n]) cout << "Yes" << '\n'; else cout << "No" << '\n'; return; }