zoukankan      html  css  js  c++  java
  • Codeforces Round #579 (Div. 3)训练总结及题解A-F

    这场心态和状态不是特别好,Awa了一发,B读题慢,C读错wa了2发,Ewa了7发,D没耐心写下去,F场后学的。
    总结:

    1. 要调整wa题的心态。
    2. A题写慌了在判断条件加了个东西
    3. C题the num of需要敏感,wa的另一发是if判断条件。
    4. D题缓下来推一推就出来了,总是没想好子序列。
    5. E题map

    题解:
    A.
    题意:判断n个数是否按1-n或n-1顺序组成一个环。
    思路:暴力
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
     
    int main(){
        IO;cout.precision(10);cout<<fixed;
        int t;cin>>t;
        while(t--){
            int n;cin>>n;
            vector<int>a(n);
            forn(i,n) cin>>a[i];
            bool ok1 = 1,ok2 = 1;
            forn(i,n){
                int x = 0;
                if(i) x = a[i-1]+1;
                else x = a[n-1]+1;
                if(x>n) x-=n;
                if(x!=a[i]) ok1 = 0;
            }
            forn(i,n){
                int x = 0;
                if(i) x = a[i-1]-1;
                else x = a[n-1]-1;
                if(x<1) x+=n;
                if(x!=a[i]) ok2 = 0;
            }
            if(ok1||ok2) cout<<"YES"<<'
    ';
            else cout<<"NO"<<'
    ';
        }
        return 0;
    }
    

    B.
    题意:4*n个数能否组成n个矩形,且矩形面积一样。
    思路:stl
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
    
    int main(){
        IO;cout.precision(10);cout<<fixed;
        int t;cin>>t;
        while(t--){
            int n;cin>>n;
            multiset<int>s;
            map<int,int>mp;
            bool ok = 0;
            forn(i,n<<2){
                int x;cin>>x;
                mp[x]++;s.insert(x);
            }
            int cnt = 0;
            for(auto x:mp) cnt+=x.second/2;
            if(cnt==2*n) ok = 1;
            if(!ok){
                cout<<"NO"<<'
    ';
                continue;
            }
            set<int>ss;
            forn(i,n){
                int x = *s.rbegin();
                int y = *s.begin();
                int xx,yy;
                xx = x,yy = y;
                s.erase(s.find(xx));
                s.erase(s.find(yy));
                s.erase(s.find(xx));
                s.erase(s.find(yy));
                //cerr<<xx*yy<<'
    ';
                ss.insert(xx*yy);
            }
            if(ss.size()==1) cout<<"YES"<<'
    ';
            else cout<<"NO"<<'
    ';
        }
        return 0;
    }
    

    C.
    题意:问n个数的共同因子有几个
    思路:gcd的因子有几个
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(ll i=0;i<n;i++)
    #define for1(i,n) for(ll i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const ll inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
     
    int main(){
        IO;cout.precision(10);cout<<fixed;
        ll n;cin>>n;
    	ll x = 0;
    	forn(i,n){
    		ll y;cin>>y;x = __gcd(x,y);
    	}
        ll cnt = 0;
        ll m = sqrt(x);
        for1(i,m){
            if(x%i==0) cnt++;
            if(x%i==0&&x/i!=i) cnt++;
        }
        cout<<cnt<<'
    ';
        return 0;
    }
    

    D.
    题意:两个字符串s,t删除s的子串使得剩下部分的子序列可以构成t。求删除的最长长度。
    思路:双指针,注意删除中间的部分。
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
    const int maxn = 2e5+5;
    int l[maxn],r[maxn];
     
    int main(){
        IO;cout.precision(10);cout<<fixed;
        string s,t;cin>>s>>t;
        int len = s.size(),len2 = t.size();
        forn(i,len){
            l[i+1] = l[i];
            if(l[i+1]<len2&&s[i]==t[l[i+1]]) l[i+1]++;
        }   
        r[len] = len2;
        for(int i = len-1;i>=0;i--){
            r[i] = r[i+1];
            if(r[i]>=0&&s[i]==t[r[i]-1]) r[i]--;
        }
        int ans = 0,p = 0;
        // forn(i,len) cerr<<l[i]<<' ';
        // cerr<<'
    ';
        // forn(i,len) cerr<<r[i]<<' ';
        // cerr<<'
    ';
        forn(i,len){
            while(p<len&&l[i]+1>r[p+1]) p++;
            // cerr<<i<<' '<<p<<'
    ';
            ans = max(ans,p-i);
         //   else break;
        }
        cout << ans<<'
    ';
        return 0;
    }
    

    E.
    题意:每次可以使数字+1,-1。求最多有多少种数字。
    思路:出现1-2次的优先向下取。
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
     
    int main(){
        IO;cout.precision(10);cout<<fixed;
        int n;cin>>n;
        multiset<int>s;
        map<int,int>mp;
        forn(i,n){
            int x;cin>>x;
            s.insert(x);mp[x]++;
        }    
        for(auto x:s){
            if(x>1&&!mp[x-1]){
                mp[x]--;
                mp[x-1]++;
            }
            if(mp[x]>1){
                mp[x]--;
                mp[x+1]++;
            }if(!mp[x]) mp.erase(x);
        }
        cout << mp.size()<<'
    ';
       // cout<<mp[1000]<<'
    ';
       // cout<<mp.size()<<'
    ';
        return 0;
    }
    

    F.
    题意:100个关卡有进关门槛ai,通关获得bi(可-可+),初始有r的金币,只有r>=ai才能进入,进入之后r+=b[i],如果r<0那么直接游戏失败,此外通关次数++。
    思路:
    bi>0的时候优先通关,bi<0的时候我们考虑这种情况
    a1a2b1b2
    如果我们走12的路线那么r>=a1,r+b1>=a2,同理21r>=a1,r+b2>=a1
    所以r>=max(a1,a2-b1) r>=max(a2,a1-b2)现在假设第一种max最小那么
    max(a1,a2-b1)<=max(a2,a1-b2),显然a1<a1+b2 a2<a2+b1,那么a2显然不是第二个式子的max
    所以a2-b1<a1-b2
    可得a2+b2<a1+b1这种情况下优先选择1再选2。所以我们按照a+b排序。
    之后01背包即可。
    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define forn(i,n) for(int i=0;i<n;i++)
    #define for1(i,n) for(int i=1;i<=n;i++)
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f;
    const int maxn = 105;
    
    int dp[maxn];
    
    bool cmp(pair<int,int> x,pair<int,int> y){
        return x.first+x.second>y.first+y.second;
    }
    
    int main(){
        IO;cout.precision(10);cout<<fixed;
        forn(i,maxn) dp[i] = -inf;
        int n,r;cin>>n>>r;
        vector<pair<int,int> >a,b;
        forn(i,n){
            int x,y;cin>>x>>y;
            if(y>=0) a.push_back({x,y});
            else b.push_back({x,y});
        }
        sort(a.begin(),a.end());
        sort(b.begin(),b.end(),cmp);
        int ans = 0;
        for(auto x:a){
            if(r>=x.first) r+=x.second,ans++;
        }
        n = b.size();
        dp[0] = r;
        forn(i,n){
            int lim = b[i].first,v = b[i].second;
            for(int j=n-1;j>=0;j--){
                if(dp[j]>=max(lim,-v)){
                    dp[j+1] = max(dp[j+1],dp[j]+v);
                    //cerr<<dp[j]<<' '<<max(lim,-v)<<'
    ';
                }
            }
        }
        for(int i = n;i>=1;i--) if(dp[i]!=-inf){
            ans+=i;
            break;
        }
        cout << ans <<'
    ';
        return 0;
    }
    
    人一我百,人十我万。
  • 相关阅读:
    CSS属性中Display与Visibility的不同
    11
    【零基础学习iOS开发】【01-前言】01-开篇
    C#计算时间差。
    C++拷贝构造函数:浅拷贝与深拷贝
    C++:string操作函数
    文件输入输出(二):文件的操作
    文件输入输出(一):重定向
    Java中的StringBuffer
    C++中setiosflags()的用法
  • 原文地址:https://www.cnblogs.com/AlexPanda/p/12520311.html
Copyright © 2011-2022 走看看