zoukankan      html  css  js  c++  java
  • Codeforces Round #673 (Div. 2)

    原题链接

    题外话

    恢复性训练

    A

    题意

    就是给定你一个操作 (a_j = a_j + a_i)(这种写法好像游标的那种。。),然后这个(a_j)如果超过一个k值,那么之后就不能进行这个操作了(就是不能在(a_j = a_j + a_i)), 问你能进行这样的操作最多多少次

    思路

    有点贪心的想法在里面, 最多的次数的话,肯定先找到这个数组中最小的那个数,然后用它去为数组中其他数进行加,才能最多

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =5.1e5;
    const int maxn = 200010;
    
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    
    
    void answer (){
     cin >> n >>m;
     for(int i=1;i<=n;i++){
        cin >>ar[i];
     }sort(ar+1 ,ar+1+n);
     LL sum =0 ;
     for(int i=2;i<=n;i++){
        sum+=(m - ar[i]) / ar[1];
     }cout <<sum <<endl;
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;
    //    sld(t);
    cin >> t ;
        while(t--)
            answer();
    
    
        return 0;
    
    }
    

    B

    题意

    给你一组数, 然后让你分给两个数组,使得这两个数组中每个数组的任意两个数相加不能等于k

    思路

    直接暴力判断就完了,把k - 当前数 分到另外一个数组就行
    注意一下如果k - 当前数没有的情况 和 k - 当前数 == 当前数的情况

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =5.1e5;
    const int maxn = 200010;
    
    
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    
    
    void answer (){
    cin >> n>> k;
    map<int , int>mp;
    for(int i=1;i<=n;i++){
        cin >>ar[i];
        mp[ar[i]] ++ ;
    }
    map<int , int > mp1,mp2;
    for(int i=1;i<=n;i++){
        if(k < ar[i])mp1[ar[i]] = mp[ar[i]] ;
        else {
            if(mp1[ar[i]] || mp2[ar[i]])continue ;
           if(mp[k-ar[i]] && !mp1[k-ar[i]]){
                mp1[k-ar[i]]= mp[k-ar[i]];
                mp2[ar[i]]= mp[ar[i]];
    
           }
           else if(!mp[k-ar[i]]){
                mp1[ar[i]] = mp[ar[i]];
           }
           if(k -ar[i] == ar[i]){
            mp1[ar[i]] = mp[ar[i]]/2 ;
            mp2[ar[i]] =(mp[ar[i]]+1)/2;
           }
        }
    }
    //cout<<mp[3]/2<<endl;
    
    for(int i=1;i<=n;i++){
        if(mp1[ar[i]])cout<<1<<" ", mp1[ar[i]] -- ;
        else cout<<0<<" ", mp2[ar[i]] -- ;
    }cout<<endl;
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;
    //    sld(t);
    cin >> t ;
        while(t--)
            answer();
    
    
        return 0;
    
    }
    
    

    C

    题意

    让你找到从1~n的每个长度中最小的公共数字(就是长度为((1<=i<=n))的每段数组子序列中都出现的数字)

    思路

    先用前缀和后缀找一下每个点一定成为公共点时的长度为多少(记录的下标应该是这个数本身, 不然后面找最小的点会很麻烦)
    双重for 第一重从1开始到n
    第二重从当前这个点一定成为公共点的长度开始遍历,找到此时没有被覆盖的点(为什么是没有覆盖的点呢,因为前面的被覆盖的点(首先是成为公共点的长度比当前点小,然后因为我们是从1 开始遍历的,也就是说如果能够成为公共点,就意味着这个点比当前这个点小,所以一定是个最小的公共点)),覆盖上即可

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =5.1e5;
    const int maxn = 200010;
    
    void clear(unsigned char *pta, int size )
    {//结构体初始化
        while(size>0)
        {
            *pta++ = 0;
            size --;
        }
    }
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    
    LL ff[N], last[N],ans[N];
    void answer (){
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >>ar[i];
    }
    for(int i=1;i<=n;i++){
        ff[i] = last[i] =0 ;
        ans[i] = -1 ;
    }
    for(int i=1;i<=n;i++){
        int x = ar[i];
        ff[x] = max(ff[x] , i - last[x]);
        last[x] = i;
    }
    for(int i=1;i<=n;i++){
        ff[i] = max(ff[i] , n - last[i] +1 ) ;
        for(int j=ff[i] ;j<=n && ans[j]==-1;j++){
            ans[j] = i;
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<" ";
    }cout<<endl;
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;
    //    sld(t);
    cin >> t ;
        while(t--)
            answer();
    
    
        return 0;
    
    }
    
    

    D

    题意

    给你一组数,问你通过(a_i =a_i -x*i , a_j = a_j+x*i(1<=i , j<=n, 0<=x<=10^9))使得这组数所有数都相等 , 然后告诉你最多(3*n次操作)

    思路

    看完题解,没想到这么简单
    因为最多操作次数是(3*n),所以对于每个数来说,其实就是进行三次操作:
    1.从第一个数那里拿数使得满足(a[i] % i ==0)
    2.把第i个数都还给第一个数
    3.等所有数都给第一个数之后,在平均分配
    由此我们可以推出 :
    1.如果这个数组之和 % n不为零的话,就不能平均分配了(这样总会有多出来的数)
    2.当为零的时候

    •  1.通过a[i] % i 是否为零来决定是否从1处获取数
      
    •  2.然后还回去
      
    •  3.分给每个数一个平均数
      

    代码

    #include <cstdio>
    #include <algorithm>
    #include<iomanip>
    #include <iostream>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <cstring>
    #include<stack>
    #include <cassert>
    #include<map>
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0)
    
    using namespace std;
    //using namespace __gnu_pbds;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const LL Max = 9.1e10;
    const int N =5.1e5;
    const int maxn = 200010;
    
    void clear(unsigned char *pta, int size )
    {//结构体初始化
        while(size>0)
        {
            *pta++ = 0;
            size --;
        }
    }
    
    LL   n, k, m ;
    LL ar[N],br[N];
    LL i,j,g;
    LL MOD = 998244353 ;
    
    //f是该长度最小的坐标 ans 是最后输出的数 , last 是相同的数上一个位置
    
    LL fac[N],inv_fac[N];
    //快速幂
    LL qpow(LL x, LL y ){
        x%=MOD;
        long long res=1%MOD;
        while(y){
            if(y&1)res=res*x%MOD;
            y>>=1;
            x=x*x%MOD;
        }
        return res;
    
    }
    
    void pre(){
        fac[0] =1 ;
        for(int i=1;i<N;i++){
            fac[i] =fac[i-1] * i %MOD;
        }
        inv_fac[N - 1 ] = qpow(fac[N - 1] , MOD-2 ) ;
    
        for(int i =N-2 ;i>=0 ;i--){
            inv_fac[i] = inv_fac[i+1] * (i+1) %MOD;
        }
    
    }
    
    LL C (LL a ,LL b){
        if(a<0 || b> a )//因为是C(a,b) 所以b《= a
        {
            return 0;
        }
    
        return fac[a] * inv_fac[b] % MOD *inv_fac[a-b]%MOD;//a 的阶乘 / ( b的阶乘 * (a-b的阶乘))
    
    }
    
    void answer (){
     cin >>n;
     LL sum =0 ;
     for( i=1;i<=n;i++){
        cin >>ar[i];
        sum +=ar[i];
     }
     if(sum%n){cout<<-1<<endl; return ;}
     cout<<3*(n-1)<<endl;
     for( i=2;i<=n;i++){
        cout<< 1 <<" "<< i <<" "<<(ar[i]%i ? i - (ar[i]%i) : 0 )<<endl;
        cout<< i <<" "<<1  <<" "<<(ar[i] + i -1 )/ i<<endl ;
     }
     sum/=n;
     for(int i=2;i<=n;i++){
        cout<< 1 <<" "<< i <<" "<< sum<<endl;
     }
       return ;
     }
    
    
    int main()
    {
    //    ios::sync_with_stdio(0);
    //    cin.tie(0), cout.tie(0);
    //       pre();
        LL t;
    //    sld(t);
    cin >> t ;
        while(t--)
            answer();
    
    
        return 0;
    
    }
    
  • 相关阅读:
    :where()和:is()
    响应式布局(媒体查询+rem)
    v-html的问题及解决办法
    Sticky Footer(粘性页脚)
    css多行文字垂直居中
    BFC
    margin负值的情况
    windows系统设置环境变量
    hash和history原生事件
    腾讯WeTest零售行业质量解决方案
  • 原文地址:https://www.cnblogs.com/gaohaoy/p/13765531.html
Copyright © 2011-2022 走看看