牛客白月赛27题解

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛27题解相关的知识,希望对你有一定的参考价值。

https://ac.nowcoder.com/acm/contest/6874#question

目录

巨木之森【树的直径】

乐团派对【贪心 / DP】

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
int a[N],n,maxv=0;
int main(void)
 
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],maxv=max(maxv,a[i]);
	if(maxv>n) puts("-1");
	else
	
		sort(a+1,a+n+1);
		int cnt=0,ans=0;
		vector<int>ve;
		maxv=0;
		for(int i=1;i<=n;i++)
		
			maxv=max(maxv,a[i]);
			cnt++;
			if(cnt==maxv) ve.push_back(cnt),ans++,cnt=0,maxv=0;
		
		if(cnt<maxv)//说明最后一个不满足,那么倒着从后返回
		
			for(int i=ve.size()-1;i>=0;i--)
			
				cnt+=ve[i],ans--;
				if(cnt>=maxv) break;
			
            ans++;
		
		cout<<ans;
	
	return 0;

光玉小镇【状压DP TSP】

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=210;
LL f[1<<17][17],dist[25][25],n,m,t;
vector< pair<int,int> >ve;
int st[N][N];
int dx[4]=-1,0,0,1;
int dy[4]=0,-1,1,0;
char c[N][N];
void bfs(int x,int y)

	st[x][y]=0;
	queue<pair<int,int>>q; q.push(x,y);
	while(q.size())
	
		auto temp=q.front(); q.pop();
		x=temp.first,y=temp.second;
		for(int i=0;i<4;i++)
		
			int tempx=x+dx[i],tempy=y+dy[i];
			if(tempx<=0||tempx>n||tempy<=0||tempy>m) continue;
			if(st[tempx][tempy]!=-1) continue;
			if(c[tempx][tempy]=='#') continue;
			st[tempx][tempy]=st[x][y]+1;
			q.push(tempx,tempy);
		
	

int main(void)

	memset(dist,0x3f,sizeof dist);
	cin>>n>>m>>t;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>c[i][j];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(c[i][j]=='S') ve.push_back(i,j);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(c[i][j]=='T') ve.push_back(i,j);
    bool flag=0;
	for(int i=0;i<ve.size();i++)
	
		memset(st,-1,sizeof st);
		bfs(ve[i].first,ve[i].second);
		for(int j=0;j<ve.size();j++) 
		
			int x=ve[j].first,y=ve[j].second;
            if(st[x][y]==-1) flag=1;//不可达
			dist[i][j]=st[x][y];
		
	
	memset(f,0x3f,sizeof f);
	f[1][0]=0;
	LL cnt=ve.size();
	for(int i=0;i<(1<<cnt);i++)
	
		for(int j=0;j<cnt;j++)
		
			if(i>>j&1)
			
				for(int k=0;k<cnt;k++)
				
					int temp=i-(1<<j);
					if(temp>>k&1) f[i][j]=min(f[i][j],f[i-(1<<j)][k]+dist[k][j]);
				
			
		
	
	LL ans=0x3f3f3f3f;
	for(int i=1;i<cnt;i++) ans=min(ans,f[(1<<cnt)-1][i]+dist[i][0]);
    if(flag) puts("-1");
	else cout<<ans+t*(cnt-1);
	return 0;

巅峰对决【线段树】

使徒袭来【二分】

#include<bits/stdc++.h>
using namespace std;
int main(void)
 
	int n; cin>>n;
	double l=1,r=n;
	while(r-l>1e-6)
	
		double mid=(l+r)/2;
		if(mid*mid*mid>=n) r=mid;
		else l=mid;
	
	printf("%.3lf",l*3);
	return 0;

#include<bits/stdc++.h>
using namespace std;
int main(void)
 
	int n; cin>>n;
	printf("%.3lf",3.0*pow(n,1.0/3));
	return 0;

核弹剑仙【dfs / 拓扑】


暴力dfs

#include<bits/stdc++.h>
using namespace std;
const int N=1e3*2+10;
int h[N],e[N],ne[N],idx;
int d[N],st[N],cnt[N],n,m;
bitset<1005>f[N];
void add(int a,int b)

	e[idx]=b,ne[idx]=h[a],h[a]=idx++;

int dfs(int u)

	st[u]=1;
	int sum=0;
	for(int i=h[u];i!=-1;i=ne[i])
	
		int j=e[i];
		if(st[j]) continue;
		sum+=dfs(j);
	
	return sum+1;

int main(void)

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
	memset(h,-1,sizeof h);
	cin>>n>>m;
	while(m--)
	
		int a,b; cin>>a>>b;
		add(b,a); 
	
	for(int i=1;i<=n;i++) 
	
		memset(st,0,sizeof st);
		cout<<dfs(i)-1<<'\\n';
	
	return 0;

拓扑

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx;
int d[N],cnt[N],n,m;
bitset<1005>f[N];
void add(int a,int b)

	e[idx]=b,ne[idx]=h[a],h[a]=idx++;

void topsort()

	queue<int>q; 
	for(int i=1;i<=n;i++) if(!d[i]) q.push(i);
	while(q.size())
	
		int u=q.front(); q.pop();
		for(int i=h[u];i!=-1;i=ne[i])
		
			int j=e[i];
			f[j]|=f[u],f[j][u]=1;
			if(--d[j]==0)  q.push(j);
		
	

int main(void)

	memset(h,-1,sizeof h);
	cin>>n>>m;
	while(m--)
	
		int a,b; cin>>a>>b;
		add(a,b); d[b]++;
	
	topsort();
	for(int i=1;i<=n;i++) cout<<f[i].count()<<endl;
	return 0;

虚空之力【贪心】

#include<bits/stdc++.h>
using namespace std;
string s1="ing";
int cnt[35],n;
string s;
int main(void)
 
	cin>>n>>s;
	for(int i=0;i<s.size();i++) cnt[s[i]-'a']++;
	int minv=1e9;
	for(int i=0;i<s1.size();i++) minv=min(minv,cnt[s1[i]-'a']);
	int sum=0;
	int temp=min(cnt['k'-'a'],minv/2);
	sum+=temp*2;
	cnt['k'-'a']-=temp,minv-=temp*2;
	temp=min(cnt['k'-'a'],minv);
	sum+=temp;
	cout<<sum;
	return 0;

社团游戏【前缀和】


暴力前缀和+剪枝。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n,m,k;
int s[N][N][26];
char c[N][N];
void init(int x,int y)

	for(int i=0;i<26;i++) 
		s[x][y][i]=s[x-1][y][i]+s[x][y-1][i]-s[x-1]<

以上是关于牛客白月赛27题解的主要内容,如果未能解决你的问题,请参考以下文章

牛客白月赛8题解

牛客白月赛4 题解

牛客白月赛11题解

牛客白月赛12题解

牛客白月赛10题解

牛客白月赛14题解