【LGR-062】洛谷10月月赛 III div.2(赛后题解)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhangjianjunab/article/details/102771907

A

小D与笔试

这种题目,写个Trie随便切。

#include<cstdio>
#include<cstring>
#define  N  110
#define  NN  11000
using  namespace  std;
struct  node
{
	int  a[30],id;
}tr[NN];int  len=1;
void  add(char  ss[],int  id)
{
	int  ed=strlen(ss+1),x=1;
	for(int  i=1;i<=ed;i++)
	{
		if(!tr[x].a[ss[i]-'a'])tr[x].a[ss[i]-'a']=++len;
		x=tr[x].a[ss[i]-'a'];
	}
	tr[x].id=id;
}
int  find(char  ss[])
{
	int  ed=strlen(ss+1),x=1;
	for(int  i=1;i<=ed;i++)x=tr[x].a[ss[i]-'a'];
	return  tr[x].id;
}
char  st[N][N],ss[5][N];
int  n,m;
inline  bool  check(int  x,int  y)
{
	if(strlen(st[x]+1)!=strlen(ss[y]+1))return  false;
	for(int  i=strlen(st[x]+1);i>=1;i--)
	{
		if(st[x][i]!=ss[y][i])return  false;
	}
	return  true;
}
char  ans[]={'A','B','C','D'};
int  main()
{
	scanf("%d%d",&n,&m);
	for(int  i=1;i<=n;i++)
	{
		scanf("%s",ss[0]+1);
		add(ss[0],i);
		scanf("%s",st[i]+1);
	}
	for(int  i=1;i<=m;i++)
	{
		scanf("%s%s%s%s%s",ss[0]+1,ss[1]+1,ss[2]+1,ss[3]+1,ss[4]+1);
		int  x=find(ss[0]);
		for(int  j=1;j<=4;j++)
		{
			if(check(x,j)==true)
			{
				printf("%c\n",ans[j-1]);
				break;
			}
		}
	}
	return  0;
}

B

小E与美食

以为很难,发现其实就是贪心,对于吃 i i 种食品,那么满足感最大的肯定是最大的前 i i 种食品啦。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define  N  310000
using  namespace  std;
int  n,a[N];
double  ans=0;
inline  bool  cmp(int  x,int  y){return  x>y;}
int  main()
{
	scanf("%d",&n);
	for(int  i=1;i<=n;i++)scanf("%d",&a[i]);
	sort(a+1,a+n+1,cmp);
	long  long  x=0;
	for(int  i=1;i<=n;i++)
	{
		x+=a[i];
		ans=max(x*1.0/i*x,ans);
	}
	printf("%lf\n",ans);
	return  0;
}

C

小C与桌游

比较简单的贪心。

对于自己获得最多的方案,就是优先编号小的。

那么是不是对于亏的少的,是不是就是一直跑编号大的?
在这里插入图片描述
不不不,对于这个图,这种做法就会走上我们的“星光大道”,直接WA声一片。还是有46pts

那么正确的贪心思想是什么呢。

我们想,如果现在就是走一个小数字,然后走一个特大数字,花费为 2 2 ,那么如果我先走目前最大的数字,把小数字免了,然后再走特大数字,是不是也是 2 2 ,很明显,后者在多数情况会更优。

那么贪心策略出来了。

对于目前的编号最大值,我们把所有能走的编号小于最大值的点都走了,直到不能走,那么再走现在能走的点钟编号最大的,然后继续重复此过程。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define  N  510000
using  namespace  std;
priority_queue<int>q1;
priority_queue<int,vector<int>,greater<int> >q2;
struct  node
{
	int  y,next;
}a[N];int  len,last[N];
inline  void  ins(int  x,int  y){len++;a[len].y=y;a[len].next=last[x];last[x]=len;}
int  n,m,in1[N],in2[N];
void  findans1()
{
	for(int  i=1;i<=n;i++)
	{
		if(!in1[i])q2.push(i);
	}
	int  mmax=0,T=n-1,ans=0;
	while(T--)
	{
		int  x=q2.top();q2.pop();
		if(x>mmax)ans++,mmax=x;
		for(int  k=last[x];k;k=a[k].next)
		{
			int  y=a[k].y;in1[y]--;
			if(!in1[y])q2.push(y);
		}
	}
	if(q2.top()>mmax)ans++;
	printf("%d\n",ans);
}
int  sta[N],tail;
void  findans2()
{
	for(int  i=1;i<=n;i++)
	{
		if(!in2[i])q1.push(i);
	}
	int  mmax=0,T=n,ans=0;
	while(T)
	{
		int  x=q1.top();q1.pop();
		mmax=x;ans++;sta[tail=1]=x;
		while(!q1.empty())sta[++tail]=q1.top(),q1.pop();
		while(tail)
		{
			T--;
			int  y=sta[tail--];
			for(int  k=last[y];k;k=a[k].next)
			{
				int  z=a[k].y;in2[z]--;
				if(!in2[z])
				{
					if(z>mmax)q1.push(z);
					else  sta[++tail]=z;//能走我的点
				}
			}
		}
	}
	printf("%d\n",ans);
}
int  main()
{
	scanf("%d%d",&n,&m);
	for(int  i=1;i<=m;i++)
	{
		int  x,y;scanf("%d%d",&x,&y);
		ins(x,y);in1[y]++;in2[y]++;
	}
	findans1();
	findans2();
	return  0;
}

D

猜你喜欢

转载自blog.csdn.net/zhangjianjunab/article/details/102771907
今日推荐