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;
 } 
View Code

 

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;
}
View Code

 

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;
}
View Code

 

posted @ 2020-09-13 23:43  Y-KnightQin  阅读(93)  评论(0)    收藏  举报