首页 > 其他分享 >『模拟赛』信友队2024CSP-S第二轮(复赛)模拟赛

『模拟赛』信友队2024CSP-S第二轮(复赛)模拟赛

时间:2024-10-20 17:00:22浏览次数:1  
标签:ch ++ st int else now 友队 2024CSP 模拟

Rank

意外地好

image

A. 坦白

签。

首先对 \(m=0\) 很好求,正着跑一遍就行。接着考虑 \(m\lt 0\) 时什么时候遗忘会更优。发现是 \(\oplus\) 操作,因此答案为偶时(即事件为奇时)遗忘会使答案 +1。为判断是否比原先优,我们提前处理出后缀和即可。这题关键在想出一个性质,\(m=i\) 是由 \(m=i-1\) 时的最优解转移来的,即遗忘的顺序对答案没有影响,那么直接正着跑一遍找最优答案即可。然后容易得出事件数量为奇时 \(m=n\) 的答案为 1,为偶时答案为 0,然后随着 \(m\) 的下降我们跑完从以这两个值为起点倒着不断 +2 知道最大值然后重复即可。

点击查看代码
#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. 秘密

不难,也算是签。

首先比较一眼的是两边往中间跑,拿到线索往两边跑是很优的,那么关键就来到了第一个拿到线索的人如何行动。手模发现站着不动总不比往左往右更优的那一个优,所以就化简成只有两种情况了。首先第一段(只有一个人有线索时)是一定要跑完的,跑完之后对于任意相邻的有线索向无线索人传递的时间都是 \(\frac{dis_{u,v}}{2}\) 的,把全部时间加和后合并,应该是 $\frac{第一个有线索的人到最另一端的距离}{2} $,那么答案就是传递到两侧较大的那一个。用 set 维护每个人的坐标,枚举两种情况的答案取优即可。

记得特殊处理第一个有线索的人是边界的情况。

点击查看代码
#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. 括号

结论题。

赛时由全部匹配的括号序列启发,发现最多可以配对 \(\lfloor{}\frac{匹配个数}{2}\rfloor{}\) 个,原因是先手玩家首次取一种括号,后手取与之不同的括号,最多可以取 \(\lceil{}\frac{匹配个数}{2}\rceil{}\) 个那种括号,因此只剩 \(\lfloor{}\frac{匹配个数}{2}\rfloor{}\) 个给先手选。而一种括号严格多的序列,如 ()(()))))),则先手一定能配对 \(\lceil{}\frac{匹配个数}{2}\rceil{}\) 个。那么思路是将整个形如 ()(()))))(())()(((())() 的序列拆成 ()(()))))(())()(((())() 三段,第一、三段和在一起看,求出最后结果应该是 \(\lceil{}\frac{ans_1+ans_3}{2}\rceil{}+\lfloor{}\frac{ans_2}{2}\rfloor{}\),但是只有 75pts。如果有大蛇能给出反例请评论留言,感激不尽。

点击查看代码(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();}

正解需要“足够好的观察力”,结论没什么技术含量,直接挂了。

image

本来想着是打着玩,然后变成了玩着打。

T1 T2 确实是玩着玩着就出来了,然后 T3 直接整不会了,憋了好久决定跳过,然后 T4 一直猜,猜过了大样例,拿了 75pts,还挺好。

感觉没什么很强的人在打信友队啊,这难度大蛇们不应该直接 AK 了?现在还是只有两个人过 T3。

一天打三场模拟赛确实累,下次还打。


完结撒花~

没图了,挂个丁真

image

标签:ch,++,st,int,else,now,友队,2024CSP,模拟
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18487504

相关文章

  • 【洛谷 P1116】车厢重组 题解(模拟+冒泡排序)
    车厢重组题目描述在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他......
  • 【洛谷 P1116】车厢重组 题解(模拟+冒泡排序)
    车厢重组题目描述在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他......
  • 【单相交流电压控制器】模拟带有两个背靠背连接的晶闸管的单相交流电压控制器(Simulink
      ......
  • CW 模拟赛 T2.迁跃
    题面似乎有原题,但是很偏挂个pdf题面下载算法一眼树形dp然而考场上没想出来很显然有一个式子令\(f_u\)表示从\(u\)进入子树,再通过迁越回到点\(u\)的最大价值则有\[f_u=\sum_{exist\text{}u\rightarrowv}^{(v,w)}\max(f_v+w-k,0)\]但是我们并......
  • 深入优化MySQL深度分页:从第10000页出发,Java模拟高效分页技巧
    在深度分页(如LIMIT99990,10)中,SQL的优化方式主要是为了避免MySQL在执行时需要扫描大量的无用数据,从而提高查询效率。以下是几种常见的SQL层面的优化方法:1.使用覆盖索引优化覆盖索引是一种索引优化技术,即查询只通过索引就可以获得所需的数据,而不需要访问实际的数据......
  • P5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III
    Sol蒲公英题意基本相同,但是注意到空间限制62.5MB,显然不能用蒲公英的做法。考虑先把整块的答案算出来,然后把小块的部分补上去,显然大块可以预处理,小块可以直接暴力查询是否越界。代码很简单。Code#include<iostream>#include<iomanip>#include<cstdio>#include<vector>......
  • 信友队2024CSP-S第二轮(复赛)模拟赛
    2024CSP-S第二轮(复赛)模拟赛\(T1\)A.坦白\(30pts\)部分分\(30pts\):爆搜。点击查看代码llans[300010];chars[300010];intmain(){freopen("confess.in","r",stdin);freopen("confess.out","w",stdout);llt,n,cn......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛09
    Rank还行A.排列最小生成树(pmst)签,有点可惜。考虑连\(i\)与\(i+1\)时,所有边边权都是小于\(n\)的,因此我们只考虑边权小于\(n\)的边即可。因为边权为\(|p_i-p_j|\times|i-j|\),所以只考虑\(|p_i-p_j|\lt\sqrt{n}\)和\(|i-j|\lt\sqrt{n}\)的情况,每个点只用连......
  • 「模拟赛」多校 A 层联训 8
    A.排列最小生成树(pmst)大家都没签上的签到调参调到110能过?!但赛时用set这个大常数选手存的边,挂了个log,所以跑不动大样例。正解:发现只按把编号相邻的点连边构成一条链,此时所有边的长度都\(\len\),所以无论如何我们都能保证最小生成树每条边的边权\(\len\)。那么我们......
  • 多校A层冲刺NOIP2024模拟赛09
    又双叒叕垫底啦rank4,T150,T2100,T339,T435。accoder上同分,rank20排列最小生成树(pmst)打的\(O(n^2\logn^2)\)暴力发现总是存在⼀颗⽣成树,使得⽣成树⾥的所有边的边权都⼩于\(n\)。考虑Kruskal的过程,我们只需要留下那些边权⼩于\(n\)的边。然后用桶排序即可。点......