2025牛客寒假算法基础集训营2题解
C.字符串外串
由D题所知,当长度为K的字符串的头尾在其前后出现过,可爱度即可为K,那么很容易构造出以下序列:{a....z}(长度为n-m的不重复序列){a....z}(a到z的循环);那么在只考虑字符串头(即字母a)在前方出现且位于下标n-m+1的位置,同理考虑字符串尾在后方出现可构造以下序列:{a..z}(a到z的循环){a...z}(长度为n-m的不重复序列),当头部可以满足可爱度为K后,尾部只要不超过K即可所以尾部{a...z}的长度只要小于等于n-m即可,那么通过取余可以快速解决
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define all(x) x.begin(),x.end()
#define int long long
using namespace std;
const int N = 2e5 + 10;
const int MOD = 998244353;
void solve() {
int n, m;
cin >> n >> m;
if (n == m || n - m > 26) {
cout << "NO\n";
return;
}
cout << "YES\n";
for (int i = 0; i < n; i++) {
cout << (char) ('a' + i % (n - m));
}
cout <<'\n';
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int _ = 1;
cin >> _;
while (_--) {
solve();
}
return 0;
}
D. 字符串里串
当存在字符串ab=a...b时,即可满足前面连续后面连续,例如有字符串abcdedcds时,
abcd=ab(cded)cd合法,那么abcd=abc(dedc)d一定也合法,即可得到只要长度为k的字符串的最后一个字符在后面的字符串中出现过即可构成合法的相等连续与不连续子串,同理第一个字符在前面出现也可以。(注意非连续子串最少长度要为2)。
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define all(x) x.begin(),x.end()
#define int long long
using namespace std;
const int N = 2e5 + 10;
const int MOD = 998244353;
vector<int> lst(30); //字符最后一次出现位置
vector<int> fst(30); //字符第一次出现位置
void solve() {
int n;
cin >> n;
string s;
cin >> s;
s = ' ' + s;
for (int i = 1; i <= n; i++) {
if (!fst[s[i] - 'a']) {
fst[s[i] - 'a'] = i;
}
lst[s[i] - 'a'] = i;
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (lst[s[i] - 'a'] > i) ans = max(ans, i);
if (fst[s[i] - 'a'] < i) ans = max(ans, n - i + 1);
}
if (ans == 1) ans = 0;
cout << ans << '\n';
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
H.一起画很大的圆!
三个点越接近直线画出的圆越大,那么就找较长的边取最直的线即可
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define all(x) x.begin(),x.end()
#define int long long
using namespace std;
const int N = 2e5 + 10;
const int MOD = 998244353;
void solve() {
int a, b, c, d;
cin >> a >> b >> c >> d;
if (abs(a - b) > abs(c - d)) {
cout<< a << ' ' << c + 1 << '\n';
cout<< b - 1 << ' ' << c << '\n';
cout << b << ' '<< c << '\n';
} else {
cout<< a << ' ' << c << '\n';
cout<< a << ' ' << c + 1 << '\n';
cout<< a + 1 << ' ' << d << '\n';
}
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int _ = 1;
cin >> _;
while (_--) {
solve();
}
return 0;
}
E.一起走很长的路!
若存在一块牌
(其中最大值用st表处理即可)
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
#define all(x) x.begin(),x.end()
#define int long long
using namespace std;
const int N = 2e5 + 10;
const int MOD = 998244353;
vector<int> a(N), pre(N), d(N);
vector<vector<int>> st(N, vector<int>(30));
void build(int n) {
for (int j = 1; (1 << j) <= n; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
}
int find(int l, int r) {
int k = log2(r - l + 1);
return max(st[l][k], st[r - (1 << k) + 1][k]);
}
void solve() {
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) {
cin >> a[i];
d[i] = a[i] - pre[i - 1];
pre[i] = a[i] + pre[i - 1];
st[i][0] = d[i];
}
build(n);
while (q--) {
int l, r;
cin >> l >> r;
if (l == r) {
cout << 0 << '\n';
continue;
}
cout << max(0ll, find(l , r) + pre[l - 1]) << '\n';
}
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!