大一选拔赛 Day1

传送门 hyflshhl

A、B、E、F比较简单

C、D难一些

 

A题:注意排序,如果l和r相等,优先删除长度小的;比较简单;

B题:是个很简单的概率DP,注意状态转移;

C题:详解在下面;

D题:详解在下面;

E题:倒序处理一下就好了,有个思路很有趣,就是将字母序看作k进制数,然后从个位加1,进位……实现起来麻烦一些;

F题:可以把序列处理成一个环,切割就是将环切断,把序列处理为两倍的长度等同于环;

 

A的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct hh {int l,r,len;}a[600001];
int n,ans,inf=2147483647;
int calc_r()
{
	int cnt=inf;
	for(int i=1;i<=n;i++) if(i<n) cnt=min(a[i].r,cnt);
	return cnt;
}

int calc_l()
{
	int cnt=-111;
	for(int i=1;i<=n;i++) if(i<n) cnt=max(cnt,a[i].l);
	return cnt;
}
bool cmp(hh x,hh y)
{
	if(x.l<y.l) return true;
	else if(x.l>y.l) return false;
	else if(x.len>y.len) return true;
	return false;
}

bool cmp2(hh x,hh y)
{
	if(x.r>y.r) return true;
	else if(x.r<y.r) return false;
	else if(x.len>y.len) return true;
	return false;
}
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i].l>>a[i].r,a[i].len=a[i].r-a[i].l;
	sort(a+1,a+n+1,cmp);
	ans=max(calc_r()-calc_l(),calc_r()-calc_l());
	sort(a+1,a+n+1,cmp2);
	ans=max(ans,calc_r()-calc_l());
	if(ans<0) ans=0;
	cout<<ans;
	return;
}

int main()
{
	solve();
	return 0;
}

B的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,n1,n2,I;
double dp[2003][2002],ans,p;

void solve()
{
	cin>>n>>n1>>n2>>I>>p;
	p/=100;
	dp[0][0]=1,dp[1][0]=1-p,dp[1][1]=p;
	for(int i=2;i<=n;i++) dp[i][0]=dp[i-1][0]*(1-p);
	for(int i=2;i<=I;i++)
		for(int j=1;j<=n2 && j<=i;j++)
			dp[i][j]=dp[i-1][j-1]*p+dp[i-1][j]*(1-p);
	for(int j=0;j<=n2-1;j++) ans+=dp[I-1][j];
	printf("%.7lf",ans);
}

int main()
{
	solve();
	return 0;
}

C的代码:

维护一个堆,记录每个状态(选n个数字)的概率;

每次取最大概率加到答案中,更新下一个状态,即把每行数字的头移向前一个;

cnt.head[i]:在cnt这个状态下,第i行数字头的位置;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAXN=105;

double ma[MAXN][MAXN];
int n,m,k;
double ans;

struct hh {int head[MAXN];double sum;}cnt;
bool operator < (hh x,hh y) {return x.sum < y.sum;}
priority_queue<hh>q;


void solve()
{
	cin>>n>>m>>k;
	cnt.sum=1.0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			cin>>ma[i][j],ma[i][j]/=100;
		sort(ma[i]+1,ma[i]+m+1),cnt.head[i]=m,cnt.sum*=ma[i][m];
	}
	q.push(cnt);
	while(!q.empty() && k)
	{
		k--;
		cnt=q.top(),q.pop();
		ans+=cnt.sum;
		for(int i=1;i<=n;i++)
		{
			hh v=cnt;
			if(!ma[i][v.head[i]]) continue;
			v.head[i]--;
			v.sum=(v.sum/ma[i][v.head[i]+1])*ma[i][v.head[i]];
			q.push(v);
		}
	}
	printf("%.8lf ",ans);
	return;
}

int main()
{
	solve();
	return 0;
}

D的代码:

参考:https://blog.csdn.net/Code92007/article/details/101350037

两遍Dijkstra处理最短路,记录每个点被最短路经过的次数;

在数组第二维中,0表示以1为起点,1表示以n为起点

dis[i][0/1]:起点到i点的最短路长度;

num[i][0/1]:起点到终点的最短路,以1/n为起点经过i点的次数;

则i点经过的概率为(num[i][1]*num[i][0])/最短路总条数;

注意对于麻花图,可能存在2^100000条最短路;

因此取ln为底,e^a+e^b=e^( a+ln (1+e^(b-a)) ) 

WA了16次,刚开始是因为没有注意到特殊图的存在;

后来是因为没有开long long?第二次了……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<cmath>
using namespace std;

typedef long long ll;
const ll MAXN=300001;
const ll inf=2e18;
ll fst[MAXN<<1],nxt[MAXN<<1];
ll dis[MAXN][2];
ll n,m,tot;
bool vis[MAXN];
double cnt[MAXN][2];

struct hh {ll f,t;ll c;}ma[MAXN<<1];
struct sh {ll num;ll d;};
bool operator < (sh x,sh y){return x.d>y.d;}
priority_queue<sh>q;

void build(ll f,ll t,ll c)
{
	ma[++tot]=(hh){f,t,c};
	nxt[tot]=fst[f];
	fst[f]=tot;
	return;
}

double calc(double x,double y)
{
	if(x<y) swap(x,y);
	return x+log(1+exp(y-x));
}

void Dijkstra(ll xx,ll st)
{
	memset(vis,0,sizeof(vis));
	for(ll i=1;i<=n;i++) dis[i][st]=inf;
	dis[xx][st]=0,q.push((sh){xx,0});
	while(!q.empty())
	{
		ll x=q.top().num;
		q.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(ll i=fst[x];i;i=nxt[i])
		{
			ll v=ma[i].t;
			if(dis[v][st]>dis[x][st]+ma[i].c)
			{
				cnt[v][st]=cnt[x][st];
				dis[v][st]=dis[x][st]+ma[i].c;
				q.push((sh){v,dis[v][st]});
			}
			else if(dis[v][st]==dis[x][st]+ma[i].c)
				cnt[v][st]=calc(cnt[v][st],cnt[x][st]);
		}
	}
	return;
}

void solve()
{
	scanf("%lld%lld",&n,&m);
	for(ll i=1;i<=m;i++)
	{
		ll f,t,c;
		scanf("%lld%lld%lld",&f,&t,&c);
		build(f,t,c),build(t,f,c);
	}
	Dijkstra(1,0),Dijkstra(n,1);
	for(ll i=1;i<=n;i++)
	{
		double ans=0;
		if(dis[i][0]+dis[i][1]==dis[n][0])
			ans=exp(cnt[i][0]+cnt[i][1]-cnt[n][0]);
		printf("%.8lf ",ans*2.0);
	}
	return;
}

int main()
{
	solve();
	return 0;
}

E的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
const int MAXN=200001;
char a[MAXN];
int vis[MAXN];
int n,m;
string s;
int maxx=-1,minn=214748444,cnt;
int f(int x)
{
	for(int i=(int)a[x]+1;i<=126;i++)
	if(vis[i])  return i;
	return 0;
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		vis[a[i]]++;
		minn=min(minn,(int)a[i]);
	}
	if(n<m)
	{
		for(int i=1;i<=n;i++) cout<<a[i];
		for(int i=1;i<=m-n;i++) cout<<(char)minn;
		return;
	 } 
	for(int i=m;i>=1;i--)
	{
		int flag=f(i);
		if(flag)
		{
			for(int j=1;j<=i-1;j++)
			cout<<a[j];
			cout<<char(flag);
			for(int j=i+1;j<=m;j++) cout<<(char)minn;
			return;
		}
	}
	return;
}

int main()
{
	solve();
	return 0;
}

F的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;

string s;
int a[600001];
int ans=-1,cnt,n,last;
void solve()
{
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='b') a[i+1]=0;
		else a[i+1]=1;
	}
	n=s.size();
	for(int i=1;i<=n;i++)
		a[i+n]=a[i];
	int i=2;
	while(i<=n*2)
	{
		cnt=1;
		if(a[i]!=a[i-1])
		{
			last=i-1;
			while(a[i]!=a[i-1] && i<=n*2)
			{ 
				if(i-last==n) {cout<<n;return;}
				i++,cnt++;
			}
			i--;
		}
		ans=max(ans,cnt);
		i++;
	}
	cout<<ans;
}

int main()
{
	solve();
	return 0;
 } 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯是中国著名的计算机竞赛之一,包括蓝桥杯全国软件和信息技术专业人才大赛以及蓝桥杯全国青少年程序设计比赛。其中,蓝桥杯python选拔赛是为了选拔具有优秀python编程能力的参赛者而举办的赛事。 蓝桥杯python选拔赛注重考察参赛者对python语言的理解和应用能力。在比赛中的题目往往涵盖了python编程的各个方面,包括基本语法、数据结构、算法设计和程序设计思维等。选手需要在规定的时间内,按照题目要求,使用python语言编写解决方案。 参加蓝桥杯python选拔赛可以提高参赛者的编程能力和解决问题的能力。通过参加比赛,选手们可以接触到各种不同类型的编程题目,锻炼自己的编程思维和动手能力。同时,比赛还提供了一个交流和学习的平台,选手们可以与其他参赛者分享经验、学习别人的优秀解法,提高自己的编程水平。 此外,蓝桥杯python选拔赛还是选拔参加蓝桥杯全国软件和信息技术专业人才大赛的入场券。优秀的选手将有机会代表自己的学校或单位参赛,并在比赛中展示自己的才华。 总之,蓝桥杯python选拔赛是一个提高编程水平、展示自己才能的良好平台。参加比赛不仅可以锻炼自己的编程能力,还可以结识其他编程爱好者,促进学习和交流。相信通过努力和参与,每个选手都能在蓝桥杯python选拔赛中获得进步和收获。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值