Codeforces Round #656 (Div. 3)垫底祭

退役一周年祭

A

没看清是任意顺序耽误了几分钟,首先最大值应该>=2个,若是3个则都为最大值,否则就两个次大值一个最大值

#include<bits/stdc++.h>
using namespace std;
int T,a[3];
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>a[0]>>a[1]>>a[2];
        int mx=a[0],num=1;
        for(int i=1;i<=2;i++)if(a[i]>mx)mx=a[i],num=1;else if(a[i]==mx)num++;
        if(num==1)puts("NO");
        else{
            puts("YES");
            if(num==3)printf("%d %d %d\n",a[0],a[0],a[0]);
            else if(a[0]!=mx)printf("%d %d %d\n",a[0],a[0],a[1]);
            else if(a[1]!=mx)printf("%d %d %d\n",a[1],a[0],a[1]);
            else printf("%d %d %d\n",a[0],a[2],a[2]);
        }
    }
}
View Code

B

直接输出未出现过的即可

#include<bits/stdc++.h>
using namespace std;
int T,n,a[90];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)a[i]=0;
        for(int i=1,x;i<=2*n;i++)
        {
            scanf("%d",&x);
            if(!a[x])a[x]=1,printf("%d ",x);
        }
        puts("");
    }
}
View Code

C

从后往前,找最长的单峰序列

#include<bits/stdc++.h>
using namespace std;
int n,a[200500];
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        int p=n;
        while(p>1&&a[p-1]>=a[p])p--;
        while(p>1&&a[p-1]<=a[p])p--;
        printf("%d\n",p-1);
    }
}
View Code

D

区间DP,写法可以仿照线段树,复杂度O(n(logn+26))轻松通过

#include<bits/stdc++.h>
using namespace std;
const int N=131075;
int n,num,a[N],lg[N],s[N][26];
char str[N];
int bushi(int l,int r,int now){return r-l+1-(s[r][now]-s[l-1][now]);}
int dp(int l,int r,int now)
{
    if(l==r)return a[l]!=now;
    int mid=l+r>>1,sl=dp(l,mid,now+1),sr=dp(mid+1,r,now+1);
    return min(sl+bushi(mid+1,r,now),sr+bushi(l,mid,now));
}
int main()
{
    lg[0]=1;for(int i=1;i<=16;i++)lg[1<<i]=i;
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%s",&n,str+1);
        for(int i=1;i<=n;i++)a[i]=str[i]-'a';
        for(int i=1;i<=n;i++)for(int j=0;j<26;j++)s[i][j]=s[i-1][j]+(a[i]==j);
        printf("%d\n",dp(1,n,0));
    }
}
View Code

E

我弱智了,实际上直接topsort判环,然后可以得到一个拓扑序列,把边从拓扑序列靠前的连向靠后的就行了,原图无环一定能构造

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int N=2e5+7;
int n,m,cnt,tot,deg[N],hd[N],v[N<<1],nxt[N<<1],pos[N],q[N];
vector<pair<int,int> >e;
void add(int x,int y){v[++cnt]=y,nxt[cnt]=hd[x],hd[x]=cnt;}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        e.clear(),cnt=tot=0;
        for(int i=1;i<=n;i++)pos[i]=deg[i]=hd[i]=0;
        for(int i=1,t,x,y;i<=m;i++)
        {
            scanf("%d%d%d",&t,&x,&y);
            e.push_back(make_pair(x,y));
            if(t==1)add(x,y),deg[y]++;
        }
        int qs=0,qe=0;
        for(int i=1;i<=n;i++)if(!deg[i])q[qe++]=i;
        while(qs<qe)
        {
            int u=q[qs++];
            pos[u]=++tot;
            for(int i=hd[u];i;i=nxt[i])if(!(--deg[v[i]]))q[qe++]=v[i];
        }
        if(tot!=n)puts("NO");
        else{
            puts("YES");
            for(int i=0;i<e.size();i++)
            {
                if(pos[e[i].fi]>pos[e[i].se])swap(e[i].fi,e[i].se);
                printf("%d %d\n",e[i].fi,e[i].se);
            }
        }
    }
}
View Code

F

贪心。如果k是1,那么答案就是n-1。k>=2时用队列把叶子数大于k的叶子入队,取出队头的时候更新叶子数。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
int n,k,ans,qs,qe,lf[N],b[N],vis[N],q[N];
vector<int>G[N];
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)G[i].clear(),lf[i]=b[i]=vis[i]=0;
        for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
        if(k==1){printf("%d\n",n-1);continue;}
        for(int i=1;i<=n;i++)
        {
            b[i]=G[i].size();
            if(b[i]==1)lf[G[i][0]]++;
        }
        ans=qs=qe=0;
        for(int i=1;i<=n;i++)if(lf[i]>=k)vis[q[qe++]=i]=1;
        while(qs<qe)
        {
            int u=q[qs++];
            ans++;
            lf[u]-=k,vis[u]=0,b[u]-=k;
            if(lf[u]>=k)vis[q[qe++]=u]=1;
            if(b[u]==1)
            {
                b[u]=0;
                for(int i=0;i<G[u].size();i++)
                if(b[G[u][i]])
                {
                    lf[G[u][i]]++;
                    if(lf[G[u][i]]>=k&&!vis[G[u][i]])vis[q[qe++]=G[u][i]]=1;
                }
            }
        }
        printf("%d\n",ans);
    }
}
View Code

G

不会写咕了

rank272 新号rating=651,为啥CF新号从rating=0算起了?上分好慢啊(不过就你div3进不了前250还想上分?)

posted @ 2020-07-18 21:54  hfctf0210  阅读(184)  评论(0编辑  收藏  举报