map<string, bool> mp;
string solve() {
string s; cin >> s;
if (mp[s]) return yes;
return no;
}
int main() {
mp["abc"] = mp["acb"] = mp["bac"] = mp["cba"] = true;
Cases
cout << solve() << endl;
return 0;
}
int solve() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
int res = 0;
for (int i = 1; i <= n; i ++) {
int t = 1;
for (int j = 0; j < n; j ++)
t *= a[j] + (j == i - 1);
res = max(res, t);
}
return res;
}
int solve() {
int res = 0;
for (int i = 1; i <= 10; i ++) {
char s[12]; cin >> s + 1;
int dx = min(i, 11 - i);
for (int j = 1; j <= 10; j ++)
if (s[j] == 'X')
res += min(dx, min(j, 11 - j));
}
return res;
}
int solve() {
int n, k; cin >> n >> k;
string s; cin >> s;
int res = 0;
for (int i = 0; i < n; i ++)
if (s[i] == 'B') i += k - 1, res ++;
return res;
}
int solve() {
int n, x; cin >> n >> x;
for (int i = 0; i < n; i ++) cin >> a[i];
ll l = 0, r = 2e9;
int res = 0;
while (l < r) {
ll mid = l + r + 1 >> 1, t = 0;
for (int i = 0; i < n; i ++) t += max(0ll, mid - a[i]);
if (t <= x) res = mid, l = mid;
else r = mid - 1;
}
return res;
}
int solve() {
int n, k; cin >> n >> k;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) cin >> h[i];
int l = 1, r = 0, res = 0, cnt = 0;
while (l <= n && r <= n) {
while (r < n && cnt + a[r + 1] <= k && (l > r || h[r] % h[r + 1] == 0)) r ++, cnt += a[r];
res = max(res, r - l + 1);
if (cnt + a[r + 1] <= k) cnt = 0, l = r + 1;
else cnt -= a[l], l ++;
}
return res;
}
题意 给定一个只含字母 A , B A,B A,B 的字符串,问最多可以进行几次下列操作(每次任选其一)
题解
AA...AA B
和 B AA...AA
可以将所有 A
消掉
AA...AA B AA...AA
只能选择消掉一边的 A
,故贪心选择消掉较长的那边,即放弃较短的一边
AA...AA B AA...AA B AA...AA
始终有一段连续的 A
消不掉,即放弃最短的连续的 A
序列
当出现连续的 B
时,通过举例容易得出肯定能全部消掉, e . g . e.g. e.g. AAA BB AA B AAA B AA
int solve() {
string s; cin >> s;
int minn = 2e5, res = 0, cnt = 0;
for (int i = 0; i < s.size(); i ++) {
if (s[i] == 'A') {
res ++;
cnt ++;
} else { // 连续的两次执行 else, 会使得 minn = 0
minn = min(minn, cnt);
cnt = 0;
}
}
minn = min(minn, cnt);
return res - minn;
}
题意 n n n 个点 n n n 条边的无向连通图, A , B A,B A,B 的起点分别为 a , b a,b a,b, A A A 追 B B B,问 B B B 是否可能永远不会被 A A A 追到
当且仅当 A , B A,B A,B 在一个点或者同时经过同一条边时, A A A 抓到 B B B
基环树
基环树(基于环的树 ),也是环套树,是一种有 n n n 个点 n n n 条边的图,简单地讲就是树上在加一条边。它形如一个环,环上每个点都有一棵子树的形式
基环树的关键就是找到环,可以先把环当作这个无根树的“根” ,也就是把环当成一个点(先不管它),这样一颗基环树就变成了一个普通的树,然后我们先按照解决普通树的方法对“根”的所有子树依次处理求解答案,最后在单独对环上所有的点进行操作求解最终答案即可。
该图只有一个环,因此 B B B 要躲避 A A A 的追击,只要比 A A A 先到环上一点即可
环上最近的点的度数为 3 3 3,因此可用拓扑排序该点
d f s dfs dfs 求 a , b a,b a,b 到环上一点的最短距离
string solve() {
int n, a, b; cin >> n >> a >> b;
vector<vector<int>> e(n + 1);
vector<int> deg(n + 1);
for (int i = 0; i < n; i ++) {
int u, v; cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
deg[u] ++, deg[v] ++;
}
if (a == b) return no;
// 拓扑排序
queue<int> q;
vector<bool> vis(n + 1);
for (int i = 1; i <= n; i ++)
if (deg[i] == 1) q.push(i);
while (!q.empty()) {
int t = q.front();
q.pop();
vis[t] = true;
for (auto i : e[t]) {
if (vis[i]) continue;
deg[i] --;
if (deg[i] == 1) q.push(i);
}
}
// 求 b 点到任意点的最短距离
for (int i = 1; i <= n; i ++) vis[i] = false;
queue<pii> qq;
qq.push({b, 0});
int pos, dis;
while (!qq.empty()) {
pii t = qq.front();
vis[t.aa] = true;
qq.pop();
if (deg[t.aa] != 1) {
pos = t.aa, dis = t.bb;
break;
}
for (auto i : e[t.aa])
if (!vis[i]) qq.push({i, t.bb + 1});
}
// 求 a 点到任意点的最短距离
for (int i = 1; i <= n; i ++) vis[i] = false;
while (!qq.empty()) qq.pop();
qq.push({a, 0});
while (!qq.empty()) {
auto t = qq.front();
vis[t.aa] = true;
qq.pop();
if (t.aa == pos) {
if (dis < t.bb) return yes;
return no;
}
for (auto i : e[t.aa])
if (!vis[i]) qq.push({i, t.bb + 1});
}
return yes;
}