『模拟赛』信友队2024CSP-S第二轮(复赛)模拟赛
Rank
意外地好
A. 坦白
签。
首先对
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x) ++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x) --)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
lx x = 0, f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
const int Ratio = 0;
const int N = 3e5 + 5;
int n;
int sum[N], mus[N];
string s;
stack<int> st;
namespace Wisadel
{
short main()
{
freopen("confess.in", "r", stdin) , freopen("confess.out", "w", stdout);
int T = qr;
while(T--)
{
cin >> s; n = s.size(); s = " " + s;
mus[n + 1] = 0;
fo(i, 1, n)
if(s[i] == '+') sum[i] = sum[i - 1] + 1;
else sum[i] = sum[i - 1] - 1;
fu(i, n, 1)
if(s[i] == '+') mus[i] = mus[i + 1] + 1;
else mus[i] = mus[i + 1] - 1;
printf("%d ", sum[n]);
int now = 0, tim = 0, fla = 0, maxx = sum[n];
fo(i, 1, n)
{// 跑最大值
if(now % 2 == 0 && now + 1 + mus[i + 1] > maxx)
{
now++, tim++;
maxx = now + mus[i + 1];
if(i == n) fla = 1;
printf("%d ", now + mus[i + 1]);
}
else if(s[i] == '+') now++;
else now--;
}
// 分情况跑完剩下的
if(n % 2 == 0)
{
int zc = 0, mit = 0;
while(now < 0 || zc < now)
{
st.push(zc), mit++;
if(now >= 0) zc += 2;
else now += 2;
}
while(mit + tim < n) st.push(now), mit++;
while(st.size()) printf("%d ", st.top()), st.pop();
}
else
{
int zc = 1, mit = 0;
while(now < 0 || zc < now)
{
st.push(zc), mit++;
if(now >= 0) zc += 2;
else now += 2;
}
while(mit + tim < n) st.push(now), mit++;
while(st.size()) printf("%d ", st.top()), st.pop();
}
puts("");
}
return Ratio;
}
}
int main(){return Wisadel::main();}
B. 秘密
不难,也算是签。
首先比较一眼的是两边往中间跑,拿到线索往两边跑是很优的,那么关键就来到了第一个拿到线索的人如何行动。手模发现站着不动总不比往左往右更优的那一个优,所以就化简成只有两种情况了。首先第一段(只有一个人有线索时)是一定要跑完的,跑完之后对于任意相邻的有线索向无线索人传递的时间都是
记得特殊处理第一个有线索的人是边界的情况。
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x) ++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x) --)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
lx x = 0, f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
const int Ratio = 0;
const int N = 2e5 + 5;
int n, m;
set<int> st;
set<int>::iterator it1, it2;
namespace Wisadel
{
short main()
{
freopen("secret.in", "r", stdin) , freopen("secret.out", "w", stdout);
n = qr, m = qr;
fo(i, 1, n)
{
int a = qr;
st.insert(a);
}
fo(i, 1, m)
{
char op; cin >> op; int x = qr;
if(op == '+') st.insert(x);
else if(op == '-') st.erase(x);
else
{
int fir, ed;
it1 = st.begin(); fir = *it1;
it1 = st.end(); it1--; ed = *it1;
it1 = it2 = st.lower_bound(x);
double ans, zc1, zc2;
if(it1 == st.begin())// 最左
ans = 1.0 * (ed - x) / 2;
else
{
it1--, it2++;
if(it2 == st.end())// 最右
ans = 1.0 * (x - fir) / 2;
else
{// 中间,向左向右取优
zc1 = 1.0 * (*it1 - fir) / 2;
zc2 = 1.0 * (ed - x) / 2;
ans = 1.0 * (x - *it1) / 2 + max(zc1, zc2);
zc1 = 1.0 * (x - fir) / 2;
zc2 = 1.0 * (ed - *it2) / 2;
ans = min(ans, 1.0 * (*it2 - x) / 2 + max(zc1, zc2));
}
}
printf("%.2lf\n", ans);
}
}
return Ratio;
}
}
int main(){return Wisadel::main();}
C. 潜力值
逆天 dXqwq csp-s 放 GF 题。
赛时由于边打边摆只打了全排列的 10pts
D. 括号
结论题。
赛时由全部匹配的括号序列启发,发现最多可以配对 ()(())))))
,则先手一定能配对 ()(()))))(())()(((())()
的序列拆成 ()(()))))
,(())()
,(((())()
三段,第一、三段和在一起看,求出最后结果应该是
点击查看代码(75pts)
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x) ++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x) --)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
lx x = 0, f = 1; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
const int Ratio = 0;
const int N = 2e5 + 5;
int n;
string s;
stack<int> st;
namespace Wisadel
{
short main()
{
freopen("bracket.in", "r", stdin) , freopen("bracket.out", "w", stdout);
int T = qr;
while(T--)
{
cin >> s;
n = s.size();
s = " " + s;
while(st.size()) st.pop();
int ans = 0, s1 = 0, s2 = 0, l = 0, r = n + 1;
fo(i, 1, n) if(s[i] != ')'){l = i; break;}
fu(i, n, 1) if(s[i] != '('){r = i; break;}
s = s.substr(l, r - l + 1);
n = s.size();
s = " " + s;
fo(i, 1, n)
{
if(s[i] == '(') st.push(i), s1++;
else
{
s2++;
if(st.size()) st.pop(), ans++;
}
}
while(st.size()) st.pop();
if(s1 == s2) ans = ans / 2;
else
{
int z1 = 0, z2 = 0, now = 0, pzuo = 0, pyou = 0, canl = 1, canr = n;
fo(i, 1, n)
{
if(s[i] == '(') st.push(i), z1++;
else
{
z2++;
if(st.size()) st.pop(), now++;
else canl = i + 1, pzuo = now;
}
}
while(st.size()) st.pop();
z1 = 0, z2 = 0, now = 0;
fu(i, n, 1)
{
if(s[i] == ')') st.push(i), z2++;
else
{
z1++;
if(st.size()) st.pop(), now++;
else canr = i - 1, pyou = now;
}
}
int zc = ans - pzuo - pyou;
ans = zc / 2 + (pzuo + pyou + 1) / 2;
}
printf("%d\n", ans);
}
return Ratio;
}
}
int main(){return Wisadel::main();}
正解需要“足够好的观察力”,结论没什么技术含量,直接挂了。
末
本来想着是打着玩,然后变成了玩着打。
T1 T2 确实是玩着玩着就出来了,然后 T3 直接整不会了,憋了好久决定跳过,然后 T4 一直猜,猜过了大样例,拿了 75pts,还挺好。
感觉没什么很强的人在打信友队啊,这难度大蛇们不应该直接 AK 了?现在还是只有两个人过 T3。
一天打三场模拟赛确实累,下次还打。
完结撒花~
没图了,挂个丁真
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探