2018_10_24 模拟赛

本文提供了JZOJ5182、JZOJ5178及JZOJ5177题目的详细分析与代码实现,涵盖数学期望计算、KMP算法与动态规划、最短路径与SPFA算法等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JZOJ 5182 码灵鼠

题目

a 0 = 1 a_0=1 a0=1
a n = a i + a j ( n ≥ 1 , i , j a_n=a_i+a_j (n\geq 1, i,j an=ai+aj(n1,i,j均在 [ 0 , n − 1 ] [0,n-1] [0,n1]内均匀随机 ) ) )
a n a_n an的期望值


分析

由于是等概率的,也就是 a n = 2 ∗ a i ( 1 ≤ i ≤ n ) a_n=2*a_i(1\leq i\leq n) an=2ai(1in)
等差数列告诉我们, a n = 2 ∗ ( 1 + n ) n 2 ÷ n a_n=2*\frac{(1+n)n}{2}\div n an=22(1+n)n÷n
综上所述, a n = n + 1 a_n=n+1 an=n+1


代码

#include <cstdio>
#define rr register
using namespace std;
unsigned n,t;
inline signed iut(){
	rr unsigned ans=0; rr char c=getchar();
	while (c<48||c>57) c=getchar();
	while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
	return ans;
}
void print(unsigned ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	t=iut();
	while (t--){
		n=iut();
		print(n+1);
		putchar(10);
	}
	return 0;
}

JZOJ 5178 So many prefix?

题目

求所有长度是偶数的前缀在字符串出现的次数和


分析

这道题其实就是kmp了,其实可以说是一道动态规划的题目
f [ i ] f[i] f[i]表示以 s [ i ] s[i] s[i]结尾的前缀出现的次数
f [ i ] = f [ f a i l [ i ] ] + [ e v e n ( i ) ] f[i]=f[fail[i]]+[even(i)] f[i]=f[fail[i]]+[even(i)]
然后统计和就行了


代码

#include <cstdio>
#include <cstring>
#define rr register
using namespace std;
char s[200001]; int len,fail[200001],f[200001];
signed main(){
	scanf("%s",s+1); len=strlen(s+1);
	for (rr int i=1,j=0;i<len;++i){
		while (j&&s[i+1]!=s[j+1]) j=fail[j];//失败指针
		fail[i+1]=(j+=(s[i+1]==s[j+1]));
		f[i+1]=(i&1)+f[fail[i+1]];//动态规划
	}
	for (rr int i=2;i<=len;++i) f[i]+=f[i-1];
	printf("%d",f[len]);
	return 0;
}

JZOJ 5177 TRAVEL

题目

在这里插入图片描述


分析

枚举通道的 l l l,spfa求出最大的 r r r,因为字典序需要最小,所以 l l l要从小到大排序,虽然分析短,但是代码毕竟也是打了很长时间的


代码

#include <cstdio>
#include <algorithm>
#include <deque>
#define rr register
using namespace std;
struct node{
	int x,y,l,r,next;
	bool operator <(const node &a)const{
	    return l<a.l;
	}
}e[6003];
int n,k,m,ls[1003],v[1003],dis[1003],ans,lll,rrr;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (c<48||c>57) c=getchar();
	while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
	return ans;
}
inline signed spfa(int val){
    rr deque<int>q; q.push_back(1); v[1]=1; dis[1]=1000001;
    for (rr int i=2;i<=n;++i) v[i]=dis[i]=0;
    while (q.size()){
    	int x=q.front(); q.pop_front();
    	for (rr int i=ls[x];i;i=e[i].next)
    	if (e[i].l<=val&&e[i].r>=val&&dis[e[i].y]<min(dis[x],e[i].r)){//如果必然会有val且当前虫洞可行
    		dis[e[i].y]=min(dis[x],e[i].r);
    		if (!v[e[i].y]){
    		    v[e[i].y]=1;
				if (q.size()&&dis[e[i].y]>dis[q.front()]) q.push_front(e[i].y);
				    else q.push_back(e[i].y);	
			}
		}
		v[x]=0;
	}    
	return dis[n];
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	n=iut(); k=iut();
	for (rr int i=1;i<=k;++i){
		rr int x=iut(),y=iut(),l=iut(),r=iut();
		if (x==y) continue;
		e[++m]=(node){x,y,l,r,0};
	}
	sort(e+1,e+1+m);
	for (rr int i=1;i<=m;++i){
		e[i+m]=e[i]; swap(e[i+m].x,e[i+m].y);
	    e[i].next=ls[e[i].x]; ls[e[i].x]=i;
	    e[i+m].next=ls[e[i+m].x]; ls[e[i+m].x]=i+m;
	}
	for (rr int i=1;i<=m;++i){
		rr int r=spfa(e[i].l);
		if (ans<r-e[i].l+1){
			ans=r-e[i].l+1;
			lll=e[i].l; rrr=r;
		}
	}
	if (ans){
		print(ans);
		for (rr int i=lll;i<=rrr;++i) 
		    putchar(i==lll?10:32),print(i);
	}
	else putchar(48);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值