题意:询问 \([l,r]\) 中是否存在 \(x,y(x\neq y)\) 使得 \(l\leq x, y, LCM(x,y)\leq r\) 。ios
思路:\(LCM(x,y)\) 一定同时是 \(x,y\) 的倍数,而且 \(x\neq y\) ,所以 \(LCM(x,y)\) 至少是 \(\min{\{x,y\}}\) 的两倍。所以直接构造一组最小的 \((x,y)\) 为 \((l,2l)\) 。c++
#include <bits/stdc++.h> #define db double using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t; cin >> t; while (t--) { long long l, r; cin >> l >> r; if (l + l > r) cout << "-1 -1\n"; else cout << l << ' ' << l + l << '\n'; } return 0; }
题意:你一开始在 \(1\) 拥有权值 \(a_1\) ,你能够向左或向右走,走到 \(i\) 增长权值 \(a_i\),可是不能连续向左走,好比不能\((5,4,3,4,5)\)可是能够 \((5,4,5,4,5)\),问走 \(k\) 步,最多向左走 \(z(\leq 5)\) 次得到的最大权值是多少。ui
思路:分红两种状况 一种是中间有 \(z\) 次向左后当即向右,另外一种是 \(z-1\) 次向左,走到最右端后向左走一步并结束。spa
每次向左并当即向右,必定是区间内最大的相邻两格的和,预处理一下。枚举 \(z\) 的值,计算,取最大值便可。code
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 5; int a[maxn]; int v[maxn], sum[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t; cin >> t; while (t--) { int n, k, z; cin >> n >> k >> z; for (int i = 1; i <= n; ++i) { cin >> a[i]; sum[i] = sum[i - 1] + a[i]; v[i] = 0; } for (int i = 2; i <= n; ++i) v[i] = max(v[i - 1], a[i] + a[i - 1]); k++; int ans = 0; for (int i = 0; i <= z; ++i) { int cnt = sum[k]; if (k - 2 * i >= 2) { int s1 = sum[k - 2 * i] + i * v[k - 2 * i]; cnt = max(s1, cnt); } if (i && k - 2 * i + 1 >= 2) { int g = k - 2 * i + 1; int s2 = sum[g] + (i - 1) * v[g] + a[g - 1]; cnt = max(cnt, s2); } ans = max(ans, cnt); } cout << ans << '\n'; } return 0; }
题意:给定一个由 \(0\text{~}9\) 构成的字符串 \(s=t_1t_2\cdots t_n\) ,询问最少从 \(s\) 中删除几个字符,使得新获得的字符串知足: \(t_2t_3\cdots t_{n-1}t_nt_1=t_nt_1t_2\cdots t_{n-2}t_{n-1}\) 。ci
思路:咱们很容易推出:\(t_1=t_3=t_5=\cdots \cap t_2=t_4=\cdots t_n\) 。所以,该字符串的构成最多只有两种字符,而且只有两种字符时,一定形如 \(121212\cdots\) 。因为该字符串由 \(0\text{~}9\) 构成,这一共只有 \(9\times9+10\) 种状况,直接暴力枚举便可。字符串
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t; cin >> t; while (t--) { string s; cin >> s; vector<vector<int> > pos(10); for (int i = 0; i < s.length(); ++i) { int x = s[i] - '0'; pos[x].push_back(i); } int ans = 0; for (int i = 0; i < 10; ++i) ans = max(ans, (int)pos[i].size()); for (int i = 0; i < 10; ++i) { for (int j = 0; j < 10; ++j) { if (i == j) continue; int cnt = 0; int l = 0, r = 0, preR = -1; while (l < pos[i].size() && r < pos[j].size()) { if (pos[i][l] < pos[j][r] && pos[i][l] > preR) { cnt += 2; preR = pos[j][r]; ++l, ++r; } else if (pos[i][l] > pos[j][r]) ++r; else ++l; } ans = max(ans, cnt); } } cout << (int)s.length() - ans << '\n'; } return 0; }
题意:给出 \(n\) 条线段 \([l_1,r_1]\) 和 \(n\) 条 \([l_2,r_2]\),每次操做能够将一条线段 \([x,y]\) 变成 \([x-1,y]\) 或 \([x,y+1]\),问最少几回操做使得每对线段交的总和大于等于 \(k\)(线段长度为 \(y-x\))。string
思路:将线段交分红三个阶段,令 \(l_1 < l_2\) 且 两条线段相离,第一阶段为 \(r_1\) 延伸到 \(l_2\), \(l_2\) 延申到 \(r_1\)(性价比 \(2\) ),第二阶段为 \(r_1\) 从 \(l_2\) 到 \(r_2\),\(l_2\) 从 \(r_1\) 到 \(l_1\)(性价比 \(1\) ),第三阶段无限延申(性价比 \(2\) )。it
显然第二阶段最合算,第1、第三阶段相同,那么枚举有几条线段完成第一阶段,而后尽可能完成第二阶段,不然第三阶段取最小值便可。io
#include <bits/stdc++.h> using namespace std; #define int long long signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t; cin >> t; while (t--) { int n, k; cin >> n >> k; int l1, r1, l2, r2; cin >> l1 >> r1 >> l2 >> r2; if (l1 > l2) swap(l1, l2), swap(r1, r2); int s1 = 0, s2 = 0; if (l2 >= r1) s1 = l2 - r1; //相交代价 //相交长度 int intersect = 0; if (l2 <= r1) intersect = min(r1, r2) - l2; //1 代价的长度 s2 = r1 - l1 + r2 - l2 - intersect * 2; if (intersect * n >= k) { cout << "0\n"; continue; } if (s1 && k <= s1) { cout << s1 + k << '\n'; continue; } int ans = 1e18; for (int i = 1; i <= n; i++) { int cnt = 0, now = intersect * n; cnt += i * s1 * 2; now += i * s1; if (now >= k) { ans = min(ans, cnt); break; } if (now + i * s2 >= k) { cnt += k - now; ans = min(ans, cnt); continue; } cnt += i * s2; now += i * s2; cnt += (k - now) * 2; ans = min(ans, cnt); } cout << ans << '\n'; } return 0; }
题意:\(\text{Berland year}\) 由 \(m\) 个月构成,每月有 \(d\) 天,每星期有 \(w\) 天。询问有几对 \((x,y)\) 知足 \(x\) 月 \(y\) 日和 \(y\) 月 \(x\) 日对应的星期几相同。
思路:转化题意为 \([(x-1)d+y] \% w = [(y-1)d+x] \% w\) ,而后进行推导:
所以,\(x-y\) 一定是 \(\frac{w}{g}\) 的倍数,简单地推一下公式便可。
#include <bits/stdc++.h> #define ll long long using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int t; cin >> t; while (t--) { ll m, d, w; cin >> m >> d >> w; if (d == 1) { cout << "0\n"; continue; } ll g = __gcd(w, d - 1); ll ww = w / g; ll top = min(d, m); ll num = (ll)floor(1.0 * top / ww); ll ans = top * num - num * (num + 1ll) / 2ll * ww; cout << ans << '\n'; } return 0; }