大一选拔赛 Day1

传送门 hyflshhl

A、B、E、F比较简单

C、D难一些

 

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

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

C题:详解在下面;

D题:详解在下面;

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

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

 

A的代码:

#include
#include
#include
#include
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(iy.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.ry.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<

B的代码:

#include
#include
#include
#include
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
#include
#include
#include
#include
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_queueq;


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
#include
#include
#include
#include
#include
#include
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_queueq;

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(xdis[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
#include
#include
#include
#include
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=1;i--)
	{
		int flag=f(i);
		if(flag)
		{
			for(int j=1;j<=i-1;j++)
			cout<

F的代码:

#include
#include
#include
#include
#include
using namespace std;

string s;
int a[600001];
int ans=-1,cnt,n,last;
void solve()
{
	cin>>s;
	for(int i=0;i

 

你可能感兴趣的:(大一选拔赛 Day1)