牛客白月赛4 题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛4 题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/134
这一套相比上一套简单些。
目录
三角形【思维 枚举】
你会发现,既然是要最长的。故这三条边一定是连在一块的。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long int LL;
typedef pair<int,int> pii;
LL n,m;
vector<pii>ve;
int main(void)
cin>>n>>m;
for(int i=0;i<n;i++)
int x; cin>>x;
ve.push_back(x,i+1);
sort(ve.begin(),ve.end());
while(m--)
int id; cin>>id;
LL a=0,b=0,c=0,flag=0;//第一条,第二条,第三条。
for(int i=n-1;i>=0;i--)
if(ve[i].second==id) continue;
c=b,b=a,a=ve[i].first;
if(a+b>c&&c!=0)//满足三角形 且三条边都有
flag=1;
break;
if(flag) cout<<a+b+c<<'\\n';
else puts("-1");
return 0;
博弈论【暴力枚举】
#include<bits/stdc++.h>
using namespace std;
string s;
int main(void)
int n; cin>>n;
while(n--)
int x;cin>>x;
s+=to_string(x);
for(int i=0;i<=2000;i++)
string a=to_string(i);
if(s.find(a)==-1)
cout<<i;
break;
return 0;
病菌感染【模拟】
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int st[N][N],n,m;
int dx[4]=-1,0,0,1;
int dy[4]=0,-1,1,0;
bool check(int x,int y)
int cnt=0;
for(int i=0;i<4;i++)
int tempx=x+dx[i],tempy=y+dy[i];
if(tempx<=0||tempx>n||tempy<=0||tempy>n) continue;
if(st[tempx][tempy]) cnt++;
return cnt>=2;
int main(void)
cin>>n>>m;
queue< pair<int,int> >q;
while(m--)
int x,y; cin>>x>>y;
q.push(x,y);
st[x][y]=1;
while(q.size())
auto temp=q.front(); q.pop();
int 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>n) continue;
if(st[tempx][tempy]) continue;
if(check(tempx,tempy)) q.push(tempx,tempy),st[tempx][tempy]=1;
bool flag=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) if(!st[i][j]) flag=0;
if(flag) puts("YES");
else puts("NO");
return 0;
郊区春游【floyd + DP】
先floyd一下,然后经典的TSP问题。
#include<bits/stdc++.h>
using namespace std;
const int N=210;
int g[N][N],w[N],f[1<<16][16];//f[i][j] 表示走了i点状态 且终点是j的最小花费
int n,m,t;
void floyd()
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
int main(void)
cin>>n>>m>>t;
for(int i=0;i<t;i++) cin>>w[i];
memset(g,0x3f,sizeof g);
for(int i=1;i<=n;i++) g[i][i]=0;
while(m--)
int a,b,c; cin>>a>>b>>c;
g[a][b]=g[b][a]=min(g[a][b],c);
floyd();
memset(f,0x3f,sizeof f);
for(int i=0;i<t;i++) f[1<<i][i]=0;
for(int i=0;i<(1<<t);i++)
for(int j=0;j<t;j++)
if(i>>j&1)
for(int k=0;k<t;k++)
if(i>>k&1)
f[i][j]=min(f[i][j],f[i-(1<<j)][k]+g[w[k]][w[j]]);
int ans=1e9;
for(int i=0;i<t;i++)
ans=min(ans,f[(1<<t)-1][i]);
cout<<ans;
return 0;
浮点数输出【签到】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
typedef long long int LL;
int main(void)
string s; cin>>s;
cout<<s;
return 0;
等价串【思维】
A绝对是由其他变的,B也是由其他变的。故0->11
将其都变成1的串,看相差的结果是不是3的倍数。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
int t; cin>>t;
while(t--)
int n,m,cnt1=0,cnt2=0;
string a,b; cin>>n>>m>>a>>b;
for(int i=0;i<a.size();i++)
if(a[i]=='1') cnt1++;
else cnt1+=2;
for(int i=0;i<b.size();i++)
if(b[i]=='1') cnt2++;
else cnt2+=2;
if((cnt1-cnt2)%3==0) puts("YES");
else puts("NO");
return 0;
黑白棋【模拟】
相邻的糖果【贪心】
贪心,从后往前推(从前到后也可以),尽可能变新加入的数。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long int LL;
LL a[N],n,m,x,sum,ans;
deque<int>q;
int main(void)
cin>>n>>m>>x;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=n;i>=1;i--)
q.push_front(a[i]);
sum+=a[i];
while(q.size()>m)
int temp=q.back();
sum-=temp;
q.pop_back();
if(q.size()==m)
stack<int>st;
while(sum>x)
LL temp=q.front();
LL w=min(sum-x,temp);
st.push(temp-w);
sum-=w;
ans+=w;
q.pop_front();
while(st.size()) q.push_front(st.top()),st.pop();
if(m>n)
LL cnt=0;
for(int i=1;i<=n;i++) cnt+=a[i];
cout<<max(0ll,cnt-x);
else cout<<ans;
return 0;
合唱队形【贪心】
先预处理,压缩一下,将相邻的1/0压到一块。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
vector<pii>ve;
int n,cnt;
string s;
int main(void)
cin>>n>>s;
for(int i=0;i<s.size();i++)
int j=i;
while(j+1<s.size()&&s[j+1]==s[i]) j++;
ve.push_back(s[i]-'0',j-i+1);
i=j;
for(int i=0;i<s.size();i++) if(s[i]=='0') cnt++;
int ans=0;
for(int i=0;i<ve.size();i++)
if(ve[i].first==0) ans=max(ans,ve[i].second);//是0
if(ve[i].first==1)//是1
if(ve[i].second==1)//只有一个
int temp=0;
if(i-1>=0&&ve[i-1].first==0) temp+=ve[i-1].second;
if(i+1<ve.size()&&ve[i+1].first==0) temp+=ve[i+1].second;
if(temp<cnt) ans=max(ans,temp+1);//可以交换
以上是关于牛客白月赛4 题解的主要内容,如果未能解决你的问题,请参考以下文章