牛客白月赛27题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛27题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/6874#question
目录
- 巨木之森【树的直径】
- 乐团派对【贪心 / DP】
- 光玉小镇【状压DP TSP】
- 巅峰对决【线段树】
- 使徒袭来【二分】
- 核弹剑仙【dfs / 拓扑】
- 虚空之力【贪心】
- 社团游戏【前缀和】
- 名作之壁【单调栈】
- 逃跑路线【思维】
巨木之森【树的直径】
乐团派对【贪心 / 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题解的主要内容,如果未能解决你的问题,请参考以下文章