round 670
A
对于第一个集合,他们的mex值是【0,100】中的第一个没有出现过的数;对于第二个集合,他们的mex值是【0,100】中的第一个没有出现过或者只出现过一次的数
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e6+10; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll ans1,ans2,t,i,n,a[maxn],x[maxn]; int main() { t=read(); while (t--) { n=read(); for (i=0;i<=100;i++) x[i]=0; for (i=1;i<=n;i++) { a[i]=read(); x[a[i]]++; } ans1=ans2=0; for (i=0;i<=100;i++) { if (x[i]==0) { ans1=i; break; } } for (i=0;i<=100;i++) if (x[i]==1 || x[i]==0) { ans2=i; break; } cout<<ans1+ans2<<endl; } return 0; }
B
当我们算出的数想为正数时,有如下几种情况:
5个正数相乘,3个正数与2个负数相乘,1个正数与4个负数相乘。
算出的数想为负数时,有如下几种情况:
5个负数相乘,3个负数与2个正数相乘,1个负数与4个正数相乘。
那么对于答案,我们肯定想要它越大越好,算出的数为正数的情况下,我们每次相乘时,那么就选用n个最大的正数和5-n个最小的负数。
算出的数为负数的情况下,我们每次相乘时,那么就选用n个最小的正数和5-n个最大的负数。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e6+10; const ll INF = 1e18; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll ans,t,n,i,a[maxn],v1[maxn],v2[maxn],cnt1,cnt2; int main() { t=read(); while (t--) { n=read(); cnt1=cnt2=0; for (i=1;i<=n;i++) { a[i]=read(); if (a[i]>0) v1[++cnt1]=a[i]; else v2[++cnt2]=a[i]; } sort(v1+1,v1+1+cnt1); sort(v2+1,v2+1+cnt2); reverse(v1+1,v1+1+cnt1); ans=-INF; if (cnt1>=0 && cnt2>=5) ans=max(ans,v2[cnt2-3]*v2[cnt2-4]*v2[cnt2]*v2[cnt2-1]*v2[cnt2-2]); if (cnt1>=1 && cnt2>=4) ans=max(ans,v2[1]*v2[2]*v2[3]*v2[4]*v1[1]); if (cnt1>=2 && cnt2>=3) ans=max(ans,v1[1]*v1[2]*v2[cnt2]*v2[cnt2-1]*v2[cnt2-2]); if (cnt1>=3 && cnt2>=2) ans=max(ans,v2[1]*v2[2]*v1[3]*v1[1]*v1[2]); if (cnt1>=4 && cnt2>=1) ans=max(ans,v1[4]*v1[1]*v1[2]*v1[3]*v2[cnt2]); if (cnt1>=5 && cnt2>=0) ans=max(ans,v1[5]*v1[4]*v1[1]*v1[2]*v1[3]); cout<<ans<<endl; } return 0; }
C
首先,第一次dfs把所有节点的儿子个数搜出来;然后,第二次dfs,若要删去这个点,则会分成多颗子树,则对于这个节点u,其子节点v的儿子总数可以直接从第一次dfs得出的答案son【v】得到,而父节点的儿子总数则是 n-son【u】。我们取这几个数中的最大值,而后统计所有节点中的最大值的最小值。如果多于1个的最小值出现,则说明我们要把一颗出现最小值的子树上面剪掉一个子节点,然后给另一个点出现最小值的子树接上;否则我们可以随便删增一条边。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e6+10; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} ll t,n,i,u,v,son[maxn],to,minn; vector <int> G[maxn],ans; void dfs(int u,int father) { son[u]=1; for (auto v:G[u]) { if (v==father) continue; dfs(v,u); son[u]+=son[v]; } } void dfs2(int u,int father) { ll maxx=-INF; for (auto v:G[u]) { if (v==father) continue; maxx=max(son[v],maxx); dfs2(v,u); } maxx=max(n-son[u],maxx); if (minn>maxx) { ans.clear(); ans.push_back(u); minn=maxx; } else if (minn==maxx) ans.push_back(u); } int main() { t=read(); while (t--) { n=read(); for (i=1;i<=n;i++) G[i].clear(); for (i=1;i<n;i++) { u=read(),v=read(); G[u].push_back(v); G[v].push_back(u); } dfs(1,1); minn=INF; ans.clear(); dfs2(1,1); if (ans.size()==1) { cout<<u<<" "<<v<<endl; cout<<u<<" "<<v<<endl; } else { to=-1; for (auto v:G[ans[0]]) if (v!=ans[1]) to=v; cout<<ans[0]<<" "<<to<<endl; cout<<ans[1]<<" "<<to<<endl; } } return 0; }

浙公网安备 33010602011771号