3.22

牛客模拟
by Hehe_0

A :游游的整数反转

题意即反转前k位,字符串翻转,直接获取长度然后反转就行,另:$ reverse $ 字符反转函数:.begin() , .end()

    int l=x.size();
    for(int i=k-1; i>=0; i--)
        cout<<x[i];
    for(int i=k; i<l; i++)
        cout<<x[i];

B:小蓝的旅游

类比一笔画问题,我们先想象思考能够满足条件的情况然后去推理找规律;因为从左上角出发到左下角,数据范围1e5纯暴力显然不可行,需要进行转化

结论:可行情况为n为偶数时或者n为奇数m也为奇数

C:先交换

显然就3种情况:
- 第一位就是奇数 》》0
- 后面有小的奇数 》》1
- 其他 》》-1

D :Crying 与选秀

挺裸的一个题,平时比赛里面我个人认为堆还是比较实用多见的,这个题写法很多样,时间上用起来也比较充裕。虽然是用set或者pq很裸,但是还是建议大家会手写大根小根堆。
我们每一个元素需要维护的值就是他的id和分数,然后for循环输入数据每一次入堆,超过六个了就弹出来一个,然后判断这个弹出来的是不是我们当前操作这个新元素,如果是就不用管,如果不是我们需要记录这个新的元素顶掉的人的id,可以直接开一个
数组记录。

if(s.size()>6)
        {
            int u=s.top().id;
            s.pop();
            if(u!=i)
            {
                cnt++;
                ans[i]=u;
            }
            else
                ans[i]=0;
        }
        else
        {
            ans[i]=0;
            cnt++;
        }

E :茉茉的密码

可能会有人说,啊,这个多串匹配超纲了,就算是哈希完了二分去找也好难写
----》任意一个公共子串 ,是不是把这个关键字眼扣出来应该都懂了吧
构造题 约等于 找规律偷鸡题
直接开桶统计字符出现情况,code略

F :最多数组数量

首先我们显然需要利用前缀和O(1)获取区间和。首先我们可以从最暴力的分段情况开始 1,2-(n-1) , n 然后对于一个确定的i或者j,来看i或者j(另一个)的可行的取值情况是单调的($p_i$>0),所以可以对于一个确定直接二分确定最大的那个i取值,然后j--,进行相同的过程

while(l<=r)
{
     if(s1>pre[i]&&s1>s2)
     	r=mid-1;
     else
         l=mid+1;
     if(s3>pre[i]&&s3>s[n]-s[l])
         ans+=n-l;
}        

G :游游的二进制树

dfs暴力,每一次延长就是左移一位

void dfs(int x,int fa,int k)
{
    if(x!=fa&&k>=l&&k<=r)
	sum++;
    for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
        if(!(y-fa))
		continue;
        if(((k<<1)+z[y])<=r)
		dfs(to,x,(k<<1)+z[y]);
	}
    return ;
}

H :最短?路径

另附:[[JLOI2011] 飞行路线]([P4568 JLOI2011] 飞行路线 - 洛谷)

第一眼是dp,经过我们转化,发现在经过一部分的路径的‘不休息’相当于累积性代价,在图上能转化为分层图的问题,分层图问题核心就是建图。

对于例如我附的裸题这种,就是把图建成k层,这k层就相当于每个点复制k次,或者理解为每一层都是我们原先的那种图,每一层都是正常连边。每层会有0权值的边链接,因为是k层所以最多使用k次免费,表示这一次我们是使用了‘免费‘的次数,复制节点的操作就是:

			add(x+j*n,y+j*n,z);
			add(y+j*n,x+j*n,z);
			add(x+j*n-n,y+j*n,0);
			add(y+j*n-n,x+j*n,0);

情况会有 (注意双向):当前的x节点在这一层走到y(花费边权/);走向下一层y(免费)

最后跑一下dij,可能我说的不太清楚,大家可以自己另外搜一下分层图这种题

			for(auto x:g[i]) 
			{
				if (dis[x][0]>a[x]+w) 
				{
					dis[x][0]=a[x]+w;
					q.push(node{dis[x][0],x,0});
				}
				if (j+1<=k&&dis[x][j+1]>w+1) 
				{
					dis[x][j+1]=w+1;
					q.push({dis[x][j+1],x,j+1});
				}
			}
posted @ 2025-03-22 18:28  Hehe_o  阅读(205)  评论(0)    收藏  举报