Codeforces Round #656 (Div. 3) (A-F)

题目:A. Three Pairwise Maximums
题意:在这里插入图片描述
找到这样的a,b,c。

显然x,y,z都是a,b,c里头的数,直接枚举a,b,c也可以。
无论a,b,c是什么大小关系,x,y,z一定要有2,3个相同的,否则NO。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,i,j,x,y,z;
        scanf("%d %d %d",&x,&y,&z);
        if(x!=y&&x!=z&&y!=z)
        {
            printf("NO\n");
            continue;
        }
        else if(x==y&&y==z)
        {
            printf("YES\n");
            printf("%d %d %d\n",x,x,x);
        }
        else
        {
            if(x==y&&x>=z)
            {
                printf("YES\n");
                printf("%d %d %d\n",x,z,z);
            }
            else if(x==z&&x>=y)
            {
                printf("YES\n");
                printf("%d %d %d\n",y,x,y);
            }
            else if(y==z&&z>=x)
            {
                printf("YES\n");
                printf("%d %d %d\n",x,x,z);
            }
            else
                printf("NO\n");
        }
    }
    return 0;
}

题目:B. Restore the Permutation by Merger
题意:问两个相同的数组(1–n)相互插入(但是同一个数组的顺序不能乱),找到这个数组的原来顺序。

直接找不同的数。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int a[200];
int book[200];
int ans[55];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(book,0,sizeof(book));
        int n,i,j,len=0;
        scanf("%d",&n);
        n*=2;
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(i=1;i<=n;i++)
        {
            if(!book[a[i]])
            {
                ans[++len]=a[i];
                book[a[i]]=1;
            }
        }
        for(i=1;i<=len;i++)
            printf("%d ",ans[i]);
        printf("\n");
    }
    return 0;
}

题目:C. Make It Good
题意:问最小删除前缀的个数,使得a数组能变为不递减c数组,每次从头或者尾放入c。

最小,所以要找后缀最大,不递减说明我们需要后缀是一个单调的序列,或者是类似开口向下的抛物线的大小规律。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
int a[200100];
int dp[200100];
int n;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        if(n==1)
        {
            printf("0\n");
            continue;
        }
        int sum=1;
        bool flag=true;;
        for(i=n-1;i>=1;i--)
        {
            if(flag)
            {
                if(a[i]>=a[i+1])
                {
                    sum++;
                }
                else
                {
                    sum++;
                    flag=false;
                }
                continue;
            }
            else
            {
                if(a[i]<=a[i+1])
                {
                    sum++;
                    continue;
                }
                else
                    break;
            }
        }
        int ans=1;
        for(i=n-1;i>=1;i--)
        {
            if(a[i]<=a[i+1])
                ans++;
            else
                break;
        }
        printf("%d\n",n-max(ans,sum));
    }
    return 0;
}

题目:D. a-Good String
题意:在这里插入图片描述问最小的变换次数让字符串为’a’-good串。

由于判断’a’-good有三种情况,依次入手。
长度大于1时,要求整个串是’a’-good,那么前n/2或者后n/2一定要是‘a’,
所以我们分治求。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=1e5+10;
double eps=1e-4;
//17
char s[131172];
int solve(int l,int r,char temp)
{
    if(l==r)
    {
        return (s[l]!=temp);
    }
    int mid=(l+r)/2;
    int suml=0,sumr=0;
    for(int i=l;i<=mid;i++)
    {
        suml+=(s[i]!=temp);
    }
    for(int i=mid+1;i<=r;i++)
    {
        sumr+=(s[i]!=temp);
    }
    return min(suml+solve(mid+1,r,temp+1),sumr+solve(l,mid,temp+1));
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j,n;
        scanf("%d",&n);
        scanf("%s",s+1);
        if(n==1)
        {
            if(s[1]=='a')
                printf("0\n");
            else
                printf("1\n");
            continue;
        }
        printf("%d\n",solve(1,n,'a'));
    }
    return 0;
}

题目:E. Directing Edges
题意:给了n个点,m条边,给的边有的是有向边有的是无向边。
问能否把无向边变有向边之后整个图没有环。没有的话,给出m条边的连接情况。

首先判段环,用拓扑排序。如果有环则NO,否则一定存在,可以画个草图,当无向边未有环没关系,有环的时候另一条边反向。之后利用拓扑排序的顺序进行建边。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=2e5+10;
double eps=1e-4;
int n,m;
vector<int>hh[MAXlen];
int INdeg[MAXlen],u[MAXlen],v[MAXlen],num,cnt[MAXlen];
queue<int>q;
void topsort()
{
    num=0;
    while(!q.empty())
        q.pop();
    for(int i=1;i<=n;i++)
    {
        if(!INdeg[i])
            q.push(i);
    }
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
        cnt[temp]=(++num);
        for(int i=0;i<hh[temp].size();i++)
        {
            int uu=hh[temp][i];
            INdeg[uu]--;
            if(INdeg[uu]==0)
            {
                q.push(uu);
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j;
        scanf("%d %d",&n,&m);
        num=0;
        for(i=0;i<=n;i++)
        {
            cnt[i]=INdeg[i]=0;
            hh[i].clear();
        }
        for(i=1;i<=m;i++)
        {
            int op;
            scanf("%d %d %d",&op,&u[i],&v[i]);
            if(op)
            {
                INdeg[v[i]]++;
                hh[u[i]].push_back(v[i]);
            }
        }
        topsort();
        if(n>num)
        {
            printf("NO\n");
            continue;
        }
        printf("YES\n");
        for(i=1;i<=m;i++)
        {
            if(cnt[u[i]]<cnt[v[i]])
                printf("%d %d\n",u[i],v[i]);
            else
                printf("%d %d\n",v[i],u[i]);
        }
    }
    return 0;
}

题目:F.Removing Leaves
题意:给定一棵n节点的树,每次你可以选择k个叶子节点删除,问最多能删几次。

有点带拓扑排序的意思,我们先找到所有的叶子节点,进行删除,用cnt[]数组记录该点子节点的删除个数,达到k个,答案++,判断度为1否,是的话加入拓扑序中。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=1e9+7;
const int MAXlen=2e5+10;
double eps=1e-4;
int n,m;
vector<int>hh[MAXlen];
int INdeg[MAXlen],num,cnt[MAXlen];
queue<int>q;
int book[MAXlen];
int k;
void topsort()
{
    while(!q.empty())
        q.pop();
    for(int i=1;i<=n;i++)
    {
        if(INdeg[i]==1)
        {
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
            book[temp]=1;
        for(int i=0;i<hh[temp].size();i++)
        {
            int uu=hh[temp][i];
            if(book[uu])
                continue;
            INdeg[uu]--;
            INdeg[temp]--;
            cnt[uu]++;
            if(cnt[uu]==k)
            {
                num++;
                cnt[uu]=0;
                if(INdeg[uu]==1)
                    q.push(uu);
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j;
        scanf("%d %d",&n,&k);
        for(i=0;i<=n;i++)
        {
            hh[i].clear();
            book[i]=cnt[i]=INdeg[i]=0;
        }
        num=0;
        for(i=1;i<n;i++)
        {
            int x1,x2;
            scanf("%d %d",&x1,&x2);
            hh[x1].push_back(x2);
            hh[x2].push_back(x1);
            INdeg[x1]++;
            INdeg[x2]++;
        }
        topsort();
        printf("%d\n",num);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43958964/article/details/107515667