Codeforces Round #790 (Div. 4) 题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #790 (Div. 4) 题解相关的知识,希望对你有一定的参考价值。
好菜好菜呀。差不多1.5h才AK。
看了一下几个朋友都是30-50分钟就AK了。感觉自己真的是太菜了。
目录
- A. Lucky?【签到】
- B. Equal Candies【签到】
- C. Most Similar Words【暴力枚举】
- D. X-Sum【枚举+模拟】
- E. Eating Queries【前缀和+二分】
- F. Longest Strike【双指针】
- G. White-Black Balanced Subtrees【dfs / 树形DP】
- H1. Maximum Crossings (Easy Version)【树状数组】
- H2. Maximum Crossings (Hard Version)【树状数组】
A. Lucky?【签到】
#include<bits/stdc++.h>
using namespace std;
int main(void)
int t; cin>>t;
while(t--)
string s; cin>>s;
int cnt1=0,cnt2=0;
for(int i=0;i<=2;i++) cnt1+=s[i]-'0';
for(int i=3;i<6;i++) cnt2+=s[i]-'0';
if(cnt1==cnt2) puts("YES");
else puts("NO");
return 0;
B. Equal Candies【签到】
#include<bits/stdc++.h>
using namespace std;
int a[105];
int main(void)
int t; cin>>t;
while(t--)
int n; cin>>n;
int minv=1e9,sum=0;
for(int i=0;i<n;i++) cin>>a[i],minv=min(minv,a[i]);
for(int i=0;i<n;i++) sum+=a[i]-minv;
cout<<sum<<'\\n';
return 0;
C. Most Similar Words【暴力枚举】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,t;
string s[N];
int solve(string a,string b)
int cnt=0;
for(int i=0;i<a.size();i++)
if(a[i]==b[i]) continue;
char c1=a[i],c2=b[i];
if(c1>c2) swap(c1,c2);
int len=c2-c1;
cnt+=len;
return cnt;
int main(void)
cin>>t;
while(t--)
cin>>n>>m;
for(int i=0;i<n;i++) cin>>s[i];
int ans=1e9;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
ans=min(solve(s[i],s[j]),ans);
cout<<ans<<'\\n';
return 0;
D. X-Sum【枚举+模拟】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=210;
int n,m,t;
LL a[N][N];
LL solve(int x,int y)
LL sum=0;
for(int i=x,j=y;i>=1&&j>=1;i--,j--) sum+=a[i][j];
for(int i=x+1,j=y+1;i<=n&&j<=m;i++,j++) sum+=a[i][j];
for(int i=x-1,j=y+1;i>=1&&j<=m;i--,j++) sum+=a[i][j];
for(int i=x+1,j=y-1;i<=n&&j>=1;i++,j--) sum+=a[i][j];
return sum;
int main(void)
cin>>t;
while(t--)
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>a[i][j];
LL sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) sum=max(sum,solve(i,j));
cout<<sum<<'\\n';
return 0;
E. Eating Queries【前缀和+二分】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
int n,m,t;
LL a[N],s[N];
bool cmp(LL a,LL b)return a>b;
int main(void)
cin>>t;
while(t--)
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n,cmp);
s[0]=a[0];
for(int i=1;i<n;i++) s[i]=s[i-1]+a[i];
while(m--)
LL x; cin>>x;
int len=lower_bound(s,s+n,x)-s;
if(s[len]>=x&&len<n) cout<<len+1<<'\\n';
else cout<<-1<<'\\n';
return 0;
F. Longest Strike【双指针】
中间因为双指针忘了移动,T麻了。后来才找到bug。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
int n,t,k;
int a[N];
int main(void)
cin>>t;
while(t--)
cin>>n>>k;
map<int,int>mp;
for(int i=1;i<=n;i++) cin>>a[i],mp[a[i]]++;
vector< pair<LL,LL> >ve;
int flag=0;
for(auto i=mp.begin();i!=mp.end();i++)
ve.push_back(i->first,i->second);
LL l=0,r=0,ans=0;
sort(ve.begin(),ve.end());
for(int i=0;i<ve.size();i++)
if(ve[i].second>=k)
int j=i;
while(j+1<ve.size()&&(ve[j+1].first-ve[j].first==1)&&ve[j+1].second>=k) j++;
if((ve[j].first-ve[i].first+1)>ans)
ans=ve[j].first-ve[i].first+1,l=ve[i].first,r=ve[j].first;
i=j;
if(!ans) cout<<-1<<'\\n';
else cout<<l<<" "<<r<<'\\n';
return 0;
G. White-Black Balanced Subtrees【dfs / 树形DP】
就是求子树的点的黑白个树是否相同。写了一下但是短路了。
于是直接用dfs序+树状数组暴力来搞。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*4+10;
int h[N],e[N],ne[N],w[N],idx;
int in[N],out[N],timestep;//进入的时间 退出的时间 时间戳
int n,m,t,st[N],tr[N];
void add(int a,int b)
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
void dfs(int u,int fa)
in[u]=++timestep;//进入的时间戳
for(int i=h[u];i!=-1;i=ne[i])
int j=e[i];
if(j==fa) continue;
dfs(j,u);
out[u]=timestep;//遍历完所有的子树退出的时间戳
int lowbit(int x)return x&(-x);
void update(int x,int c)
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
int query(int x)
int sum=0;
for(int i=x;i;i-=lowbit(i)) sum+=tr[i];
return sum;
void init(int n)
for(int i=0;i<=n;i++) tr[i]=0,h[i]=-1;
idx=0;
timestep=0;
int main(void)
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin>>t;
while(t--)
cin>>n;
init(n);
for(int i=2;i<=n;i++)
int x; cin>>x;
add(x,i),add(i,x);
string s; cin>>s;
for(int i=0;i<s.size();i++)
if(s[i]=='W') w[i+1]=0;//将白的权值弄成1
else w[i+1]=1;//黑的弄成0
dfs(1,-1);
for(int i=1;i<=n;i++) update(in[i],w[i]);//in[i] i号结点在dfs序列中的位置
int ans=0;
for(int i=1;i<=n;i++)
int sum=query(out[i])-query(in[i]-1);//白的个数
int len=out[i]-in[i]+1;//总的个数
if( (len-sum==sum )&&sum) ans++;
cout<<ans<<'\\n';
return 0;
树形DP做法。
#include<bits/stdc++.h>
using namespace std;
const int N=4010;
vector<int>ve[N];
int f[N][2];//0 w 1 B
string s;
void dfs(int u,int fa)
if(s[u]=='W') f[u][0]++;
else f[u][1]++;
for(int i=0;i<ve[u].size();i++)
int j=ve[u][i];
if(j==fa) continue;
dfs(j,u);
f[u][0]+=f[j][0],f[u][1]+=f[j][1];
int Codeforces Round #436 E. Fire(背包dp+输出路径)
[ACM]Codeforces Round #534 (Div. 2)
Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)