• Codeforces Round #633 (Div. 2)


    A. Filling Diamonds

    题意:

    (交的时候也没搞懂这个题意,犹豫好久)用一个菱形覆盖一个"4n−2triangles"的不同覆盖方法

    思路:

    可以看出来有n种覆盖方法

    代码:

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    const int N=100010;
    int main(){
        int T;
        cin>>T;
        while(T--){
            int n;
            cin>>n;
            cout<<n<<endl;
        }
        return 0;
    }
    

    B. Sorted Adjacent Differences

    题意:

    给出一个长度为n的序列:(a_1,a_2,…,a_n),构造一种序列重排后满足:(|a_1−a_2|≤|a_2−a_3|≤…≤|a)n-1(−a_n|),输出任意一种方案。

    思路:

    这种题我们一般都先按从小到大排序,然后找到某种合适的顺序。排序后可以这样构造:(a_1)(a_n)的差值是最大的,然后让(a_1,a_n)排到最后,(a_1)(a)n-1的差小于等于(a_1)(a_n)的差,但是大于不包含(a_n)的其他所有。所有用双指针从前和从后接替加入。

    代码:

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    const int N=100010;
    int a[N];
    vector<int> v;
    int main(){
        int T,n;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i=1;i<=n;++i){
                scanf("%d",&a[i]);
            }
            sort(a+1,a+1+n);
            v.clear();
            for(int i=1;i<=n/2;++i){
                v.push_back(a[i]);
                v.push_back(a[n-i+1]);
            }
            if(n%2){
                v.push_back(a[n/2+1]);
            }
            reverse(v.begin(),v.end());
            for(auto it: v) cout<<it<<" ";
            cout<<endl;
        }
        return 0;
    }
    

    C. Powered Addition

    题意:

    给出一个序列长度为n的序列,然后可以进行无数次操作,第i次可以选择任意个数(可以一个都不选),将其加上2i-1,求将序列变成非降序序列的最少操作次数。 (1≤n≤10^5,−10^9≤a_i≤10^9)

    思路:

    我们让(a[i-1]>a[i],t=a[i-1]-a[i]),t的二进制最高位1的位数就是我们使得a[i-1]<=a[i]的最小操作次数,所以当我们让a[i-1]=a[i]使用的是最小操作次数,且对于后面的限制更小,所以枚举所有不合法的前后差值,更新最高位1的位数就是答案。

    代码:

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    long long a[100010],p[60];
    int main(){
        int T;
        p[0]=1;
        for(int i=1;i<60;++i){
            p[i]=p[i-1]*2;
        }
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;++i){
                scanf("%lld",&a[i]);
            }
            int ans=0;
            for(int i=2;i<=n;++i){
                if(a[i-1]>a[i]){
                    LL t=a[i-1]-a[i];
                    int res=0;
                    //cout<<t<<endl;
                    while(t){
                        res++;
                        t>>=1;
                    }
                    ans=max(ans,res);
                    a[i]=a[i-1];
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    

    D. Edge Weight Assignment

    题意:

    给出一个无权树,给每个边上赋一个权值,使得每两个叶子节点之间的路径边权异或和位0,求权值数的种类的最少和最多各为多少。(3≤n≤10^5)

    思路:

    数最少的情况:
    当两个叶子节点之间的边数为偶数,那么这条路上的只用一种数就可以了。当边数奇数时,我们也只需要三个数就可以了:假设a-b之间边数为奇数,对于这一条单一的路径至少需要三个数是显然的,假设这条路径上有别另一条分支点d引出叶子节点c,c到d的边可以构造成异或和等于a到d的异或和,这样c到a的异或和为0,由于c到b和a到b一样,所以c到b异或和也为0.
    数最多的情况:
    若n-1条边权值都不相等,假设a到b的m条边都不相等,异或和为0,若有a的父亲节点d有另一个儿子节点c也是叶子,那么a到b的边数是2,则a到d和c到d的边权值相等,所以遍历一遍减去满足这种情况的边数。

    代码:

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    const int N=100010;
    vector<int> g[N];
    int dis[N],ans1,ans2;
    bool dfs1(int u,int fa){
        dis[u]=dis[fa]+1;
        if(dis[u]%2&&g[u].size()==1) {
            ans1=3;
           //cout<<u<<endl;
            return true;
        }
        for(int i=0;i<g[u].size();++i){
            int v=g[u][i];
            if(v==fa) continue;
            if(dfs1(v,u)) return true;
        }
        return false;
    }
    void dfs2(int u,int fa){
        int cnt=0;
        for(int i=0;i<g[u].size();++i){
            int v=g[u][i];
            if(fa==v) continue;
            if(g[v].size()==1) cnt++;
            else dfs2(v,u);
        }
        if(cnt>0){
            ans2-=cnt-1;
        }
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1,u,v;i<n;++i) {
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        ans1=1,ans2=n-1;
        int f1=0,f2=0;
        for(int i=1;i<=n;++i){
            if(g[i].size()==1&&!f1){
                dis[0]=-1;
                dfs1(i,0);f1=1;
            }
            if(g[i].size()>1&&!f2) {
                dfs2(i,0);f2=1;
            }
        }
        cout<<ans1<<" "<<ans2<<endl;
        return 0;
    }
    
  • 相关阅读:
    HDU1879 kruscal 继续畅通工程
    poj1094 拓扑 Sorting It All Out
    (转)搞ACM的你伤不起
    (转)女生应该找一个玩ACM的男生
    poj3259 bellman——ford Wormholes解绝负权问题
    poj2253 最短路 floyd Frogger
    Leetcode 42. Trapping Rain Water
    Leetcode 41. First Missing Positive
    Leetcode 4. Median of Two Sorted Arrays(二分)
    Codeforces:Good Bye 2018(题解)
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12702603.html
Copyright © 2020-2023  润新知