• Codeforces Round #642 (Div. 3) A->D(D为自定义单调队列)


    A: http://codeforces.com/contest/1353/problem/A

    题意:构造出一个长度为n的序列,sum=m。求出最大的相邻差值的绝对值之和。a[]>=0。

    解析:由于最小为0,所以可以这么构造:0,x,0,x,0,x......x为sum的平均值。那么结果总的就是2*m了。特判一下n=1和n=2

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    #define ll long long
    const int maxn=40;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            ll n,m;
            cin>>n>>m;
            if(n==1)
                cout<<'0'<<endl;
            else if(n==2)
                cout<<m<<endl;
            else
                cout<<m*2<<endl;
        }
    }

    B:http://codeforces.com/contest/1353/problem/B

    题意:长度为n的两个序列a[]和b[],a[]的元素可以和b[]交换k次,求a[]的最大和。

    解析:后台样例应该有点问题,我交了一发错的代码,但是过了。。。下面是思路正确的代码,模拟一下即可:

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    #define ll long long
    const int maxn=40;
    int a[maxn],b[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n,k;
            cin>>n>>k;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            for(int i=1;i<=n;i++)
                cin>>b[i];
            sort(a+1,a+1+n);
            sort(b+1,b+1+n);
            int ans=0;
            int j=n;
            for(int i=1;i<=n;i++)
            {
                if(ans==k)
                    break;
                if(a[i]<b[j])
                {                
                    a[i]=b[j];
                    j--;
                    ans++;
                }
            }
            int sum=0;
            for(int i=1;i<=n;i++)
                {
                    sum+=a[i];
                //    cout<<a[i]<<"  ";
                }
            cout<<sum<<endl;
        }
    }

    C:http://codeforces.com/contest/1353/problem/C

    题意:n*n的格子,每个格子各一个棋子。把所有棋子放在同一个位置所需要的最少操作数。可以朝8个方向移动。

    解析:一圈一圈加就可以。可以推出公式来:sum=sum+(2*i+(i-2)*2)*ans;

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    #define ll long long
    const int maxn=40;
    int a[maxn],b[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            ll n;
            cin>>n;
            ll sum=0;
            if(n==1)
            {
                cout<<"0"<<endl;continue;
            }
            if(n==3)
            {
                cout<<"8"<<endl;continue;
            }
            sum=8;
            ll ans=2;
            for(int i=5;i<=n;i+=2)
            {
                sum=sum+(2*i+(i-2)*2)*ans;
                ans++;
            }
            cout<<sum<<endl;
        }
    }

    D:http://codeforces.com/contest/1353/problem/D

    解析:单调队列模拟。主要是排序方法注意一下,同长度L小的在前。否则长度长的在前。

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    #define ll long long
    const int maxn=2e5+10;
    int num[maxn];
    struct node
    {
        int l,r;
        bool operator <(const node& a) const{
            if(a.r-a.l==r-l)
                return a.l<l;
                return a.r-a.l>r-l;
        }
    }st;
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            memset(num,0,sizeof(num));
            priority_queue<node>q;
            q.push(node{1,n});
            for(int i=1;i<=n;i++)
            {
                st=q.top();
                q.pop();
                int md=(st.r+st.l)/2;
                num[md]=i;
                if(md>st.l)
                    q.push(node{st.l,md-1});
                if(md<st.r)
                    q.push(node{md+1,st.r});
                
            }
            for(int i=1;i<=n;i++)
                cout<<num[i]<<" ";
                cout<<endl;
        }
    }
  • 相关阅读:
    tensorflow2.0第1章 Tensorflow简介与环境搭建
    SIGAI机器学习第二十四集 聚类算法1
    SIGAI机器学习第二十三集 高斯混合模型与EM算法
    51nod1429 巧克力
    CTSC2018 Day2T1 Juice混合果汁
    CF1B Spreadsheets
    CF2B The least round way
    【模板】点分治
    【模板】AC自动机
    【模板】网络流-最大流 Dinic
  • 原文地址:https://www.cnblogs.com/liyexin/p/12895977.html
Copyright © 2020-2023  润新知