zoukankan      html  css  js  c++  java
  • Codeforces Round #697 (Div. 3)题解报告(A-G)

    考完雅思了开始康复训练...争取以后每把都打不咕。

    A.Odd Divisor

    Editorial:偶数有个特性就是可以一直除2,所以我们只需要判断无限除2之后的奇数是不是1即可。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            ll n;scanf("%lld",&n);
            if(n%3==0){puts("YES");continue;}
            while(n%2==0){
                n/=2;
            }
            if(n==1){puts("NO");continue;}
            if(n%2==1){
                puts("YES");
            }else{
                puts("NO");
            }
        }
    }
    View Code

    B. New Year's Number

    Editorial:先尽可能把2020减去,最后会发现一些多余的数,这个时候对多余的数特判,看是否多余2020的组数即可。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            int d=n/2020;
            int re=n-d*2020;
            if(re>d) puts("NO");
            else puts("YES");
        }
    }
    View Code

    C. Ball in Berland

    Editorial:这个题刚拿到手我就想二分图做法(划掉),但是发现好像不太容易维护边与边之间的关系所以叉掉。 于是正确做法是统计a和b每个人在预配对中的数量,然后O(n)扫一遍枚举统计,因为不可能出现2组a和b都是同一个人的情况,所以mp[a]就代表和a挂钩的人,同理mp[b]代表和b挂钩的人,这时候要处理的时候记得+1,因为a和b自己有搭班。所以最后的时候就把这些结果加起来就ok啦。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int a[maxn],b[maxn];
    map<int,int> mp1,mp2; 
    int main(){
        IO;
        int T;scanf("%d",&T);
        while(T--){
            int x,y,n;scanf("%d%d%d",&x,&y,&n);
            rep(i,1,n) scanf("%d",&a[i]),mp1[a[i]]+=1;
            rep(i,1,n) scanf("%d",&b[i]),mp2[b[i]]+=1;
            ll ans=0;
            rep(i,1,n){
                ans+=(n-mp1[a[i]]-mp2[b[i]]+1);
            }
            cout<<ans/2<<endl;
            mp1.clear();mp2.clear();        
        }
    }
    View Code

    D. Cleaning the Phone

    Editorial:这个题比赛的时候没写出来qwq想着用背包去做但是背包背不下那么大的数据所以肯定得用贪心啦。做法就是对价格为1和2的分别从大到小排序之后分别预处理,以价值2的为例,肯定越往前单个体积越大,所以在每一次处理的时候二分寻找适合的最低的a就行(双指针也可以,因为方向是恒定的),还有记得开ll,扫的时候要从0开始扫

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int a[maxn],b[maxn];
    ll pre1[maxn],pre2[maxn];
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n,m;ll tot=0;scanf("%d%d",&n,&m);
            rep(i,1,n) scanf("%d",&a[i]),tot+=a[i];
            rep(i,1,n) scanf("%d",&b[i]);
            if(tot<m){puts("-1");continue;}
            vector<int> vec1,vec2;
            rep(i,1,n){
                if(b[i]==1) vec1.pb(a[i]);
                else vec2.pb(a[i]);
            }
            sort(vec1.rbegin(),vec1.rend());
            sort(vec2.rbegin(),vec2.rend());
            int cnt1=0,cnt2=0;
            for(auto it:vec1){
                pre1[++cnt1]=pre1[cnt1-1]+it;
            }
            for(auto it:vec2){
                pre2[++cnt2]=pre2[cnt2-1]+it;
            }
            ll ans=inf;
            for(int i=0;i<=cnt2;i++){
                int remain=m-pre2[i];
                ll pos=lower_bound(pre1,pre1+cnt1+1,remain)-pre1;
                if(pre2[i]+pre1[pos]>=m) ans=min(ans,2*i+pos);
            }
            printf("%lld
    ",ans);
            rep(i,1,n) pre1[i]=0,pre2[i]=0;
        }
    }
    View Code

    E. Advertising Agency

    Editorial:读完题就看出很裸的卢卡斯板子题,感觉没什么好讲的。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int a[maxn];map<int,int> mp,vis;
    bool cmp(int a,int b){
        return a>b;
    }
    ll mulit(ll a,ll b,ll m){
        ll ans=0;
        while(b){
            if(b&1) ans=(ans+a)%m;
            a=(a<<1)%m;
            b>>=1;
        }
        return ans;
    }
    
    ll quick_mod(ll a,ll b,ll m){
        ll ans=1;
        while(b){
            if(b&1){
                ans=mulit(ans,a,m);
            }
            a=mulit(a,a,m);
            b>>=1;
        }
        return ans;
    }
    
    ll comp(ll a,ll b,ll m){
        if(a<b) return 0;
        if(a==b) return 1;
        if(b>a-b) b=a-b;
        ll ans=1,ca=1,cb=1;
        for(int i=0;i<b;i++){
            ca=ca*(a-i)%m;
            cb=cb*(b-i)%m;
        }
        ans=ca*quick_mod(cb,m-2,m)%m;
        return ans;
    }
    
    ll lucas(ll a,ll b,ll m){
        ll ans=1;
        while(a&&b){
            ans=(ans*comp(a%m,b%m,m))%m;
            a/=m;
            b/=m;
        }
        return ans;
    }
    
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n,k;scanf("%d%d",&n,&k);
            set<int> s;map<int,int>cnt;
            rep(i,1,n) scanf("%d",&a[i]),mp[a[i]]+=1;
            sort(a+1,a+n+1,cmp);
            rep(i,1,k){
                s.insert(a[i]);
                cnt[a[i]]+=1;
            }
            ll ans=1;
            for(auto it:s){
                ans*=lucas(mp[it],cnt[it],mod);
            }
            cout<<ans<<endl;
            mp.clear();vis.clear();
        }
    }
    View Code

    F.Unusual Matrix

    Editorial:感觉是这套div3里思维含量最大的题了。其实仔细想想,a[i][j]的变动可能会对a[1][j]或者a[i][1]造成影响,但是呢有些时候又可以通过a[1][1]变回来。这里我要介绍一种我自己想的最简单容易理解的方法。首先我们先直接把a[i][j]和b[i][j]取XOR操作,得到c[i][j],这里我要提的一点是a要变成b,必须借c之手。所以我们现在要想的是怎么把c[i][j]变成0,那其实很简单,只需要维护刚刚我说的4个点。把他单独领出来会发现这4个点中如果有奇数个c[i][j]那肯定无法转化。所以只需要特判单偶性就行。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e3+5;
    int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            rep(i,1,n) rep(j,1,n) scanf("%1d",&a[i][j]);
            rep(i,1,n) rep(j,1,n) scanf("%1d",&b[i][j]);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    c[i][j]=a[i][j]^b[i][j];
                }
            }
            bool flag=true;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if((c[i][j]+c[1][1]+c[1][j]+c[i][1])%2==1){
                        flag=false;
                        goto end;
                    }
                }
            } 
            end:;
            if(flag) puts("YES");
            else puts("NO");
        }
    }
    View Code

    G.Strange Beauty

    Editorial:考察的是对素数筛的理解。这里我用的是埃式筛,复杂度O(nlogn),只需要统计每个数他往下有几个可行的数,然后维护最大ans,最后输出n-ans即可

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            vector<int> cnt(maxn),dp(maxn);
            rep(i,1,n){
                int x;scanf("%d",&x);
                cnt[x]+=1;
            }         
            int ans=0;
            rep(i,1,2e5){
                dp[i]+=cnt[i];
                for(int j=2*i;j<=2e5;j+=i){
                    dp[j]=max(dp[j],dp[i]);
                }
                ans=max(ans,dp[i]);
            }
            cout<<n-ans<<endl;
        }
    }
    View Code
    Codeforces ID:Anonytt QQ: 847399102 可以添加&关注
  • 相关阅读:
    Chrome调试中的奇技淫巧
    正则表达式学习记录
    探寻<a>中的href和onclick
    鼠标事件记录
    读取本地文件并进行处理
    浏览器兼容性问题汇总
    前端经验总结
    PL/sql使用总结
    正反斜杠的使用场景记录
    isEmpty和isBlank的区别
  • 原文地址:https://www.cnblogs.com/Anonytt/p/14329656.html
Copyright © 2011-2022 走看看