zoukankan      html  css  js  c++  java
  • cf605 div3

    https://codeforces.com/contest/1272

    A题  。。年轻人老想不一样的姿势。。。折腾半天直接枚举不香吗?  呸, 真香
    B题。。。没仔细看题 WA到自闭

    C题。。题目都告诉公式  n*(n+1)/2 了, 折腾半天发现不是   2^n-1不是组合数-{n,0}   然后推出 题目给的公式可还行, 对自己服气哦可真是棒呢

    D题。。。有思路但是没写出来, 时间不够。。。。

    • A题 Three Friends   直接枚举吧, 已有几种不一样的姿势提供
    • B题 Snow Walking Robot    

        //Recently you have bought a snow walking robot and brought it home

        //so the rebot should come back to the home(0, 0)
        //and notice you can't visit one point twice(except 0,0) 
        // ans += string(x, 'c'); //string copy x chars 'c'

    • C题 Yet Another Broken Keyboard    模拟跑一遍
    • D题 Remove One Element    用两个数组分别记录以 位置pos结尾 和 开始的子串的最大长度,然后 如果 v[pos] < v[pos+2] 求个max(结尾[pos]+开始[pos+2]) 即可, 也可以用 dp
    • E题 Nearest Opposite Parity 

       题意每个点可以到i+a[i] 和 i-a[i] 位置, 问最少步数 从 当前位置到另一个 奇偶性相反的位置(指a[i]  a[j] 奇偶性)

      先跑一遍记录下一次能到的点并加入队列, 并且把每个点两条路径中能走的都加入图中(二维数组存储), 接下来就遍历队列(直到队列为空) 将每次图中已有的路径能到的点 如果能通过到达该点转折就能到达一个相反parity的话  就更新下点值, 相当于 bfs 通过已有的点确定之前未被确定的点, enmmmmm 我的理解是这样   具体代码 如下

    • F题 Two Bracket Sequences    //输入两个括号序列串s t 需要把它变成合法的括号串ans , ans 需要包含 s t 的作为子序列

         如果不太明白,可以看看这个兄弟写的解释 https://codeforces.com/blog/entry/72132?#comment-563886

         通过三维dp[i][j][bal] 贪心求 s位置 i 和 t位置 j 的最小前缀长度和记录当前状态下的( 或者 ),

           每次增加一个 ( 或 )   dp求最小的前缀长度 和 所需的后缀长度,

         再由dp[n][m][cbal] 反向添加字符, 故最后需要倒一下

    #include <bits/stdc++.h>//cf605 div3
    #define ll long long
    #define _rep(i,a,b) for(int i = (a); i <= (b) ;i++)
    #define _for(i,a,b) for(int i = (a); i < (b) ;i++)
    using namespace std;
    
    void taskA(){
        int q;
        cin >> q;
        while(q--){
            int a[4]; 
            cin >> a[1] >> a[2] >> a[3];
            sort(a+1, a+4);
            ll ans = a[2]-a[1]+a[3]-a[1]+a[3]-a[2];
            if(a[3]-a[1]<=2) ans = 0;
            for(int i = 4; i > 0; i--)
                if(ans-i > 0) {ans -= i; break;}
            cout << ans << endl;
        }return;
    }
    void taskA1(){
        int q,a,b,c;
        cin >> q;
        while(q--){
            cin >> a >>b >> c;    
            ll ans= 1e18;
            _rep(i,-1,1) _rep(j,-1,1) _rep(k,-1,1){
                int x = a+i;
                int y = b+j;
                int z = c+k;
                ans = min(ans, (ll)(abs(x-y)+abs(y-z)+abs(x-z)));
            }   
            cout << ans << endl;
        }return;
    }
    void taskA2(){
        int t; cin >> t;
        while(t--){
            int a[4];
            cin >> a[1] >> a[2] >> a[3];
            sort(a+1, a+4);
            int mx = max(0, a[3]-a[1]-2);
            cout << mx*2 << endl;
        }return;
    }
    View Code
    void taskB(){
        int t; cin >> t;
        while(t--){
            string s;
            cin >> s;
            int a[27] = {}; 
            for(char ch : s) a[ch-'A']++;
            int cl = min(a['L'-'A'], a['R'-'A']);
            int cu = min(a['U'-'A'], a['D'-'A']);
            if(!cl || !cu) cl = min(cl, 1), cu = min(cu, 1);
            string ans = "";
        //cout << "cl = " << cl << "  cu = " << cu << endl;
            ans += string(cu, 'U');//_for(i,0,cu) ans += 'U';
            ans += string(cl, 'L');//_for(i,0,cl) ans += 'L';
            ans += string(cu, 'D');//_for(i,0,cu) ans += 'D';
            ans += string(cl, 'R');//_for(i,0,cl) ans += 'R';
            
            if(ans.size() == 0){ cout << "0
    
    "; continue;}
            cout << ans.size() << endl << ans << endl;
        }return;
    }
    void taskC(){
        int n,k; cin >> n >> k;
        string s; cin >> s;
        vector<int> used(27, 0);
        for(int i = 0; i < k; i++) {
            char ch; cin >> ch; cin.get();
            used[ch-'a'] = 1;
            //cout << "ch = " << ch << endl;
        }
        ll ans = 0, cnt = 0;
        for(int i = 0; i < n; i++) {
            if(!used[s[i]-'a']) {
                if(cnt > 0) ans += (cnt*(cnt+1)/2);
                cnt = 0;
            }
            else cnt++;
        }
        if(cnt > 0) ans += (cnt*(cnt+1)/2);
        cout << ans << endl;
        return;
    }
    void taskC1(){
        int n,k;
        cin >> n >>k;
        string s; cin >> s;
        vector<int> v(27,0);
        _for(i,0,k) { char ch;; cin >> ch; cin.get();v[ch-'a'] = 1;}
    
        ll ans = 0;
        _for(i,0,n){
            int pos = i;
            while(v[s[i]-'a']) i++;
            ans += 1LL*(i-pos)*(i-pos+1)/2;
        }cout << ans << endl;
        return;
    }
    View Code
    void taskD(){
        int n; cin >> n;
        vector<int> v(n+1);
        _for(i,0,n) cin >> v[i];
    
        int ans = 0;
        vector<int> r(n, 1);
        for(int i = n-2; i >= 0; i--)
        {
            if(v[i+1] > v[i]) r[i] = r[i+1]+1;
            ans = max(ans, r[i]);
        }
    
        vector<int> l(n, 1);
        _for(i,1,n)
        {
            if(v[i] > v[i-1]) l[i] = l[i-1]+1;
               ans = max(ans, l[i]);
        }
    
        _for(i,0,n-2) 
            if(v[i] < v[i+2])// 需满足才可连起
                 ans = max(ans, l[i]+r[i+2]);
        cout << ans << endl;
        return;  
    }
    void taskD1(){
        int n; cin >> n;
        int dp[N][2] = {};
        vector<int> v(n, 0);
        _for(i,0,n) cin >> v[i];
        //dp[i][0]记录以i为结尾的子串最大长度  dp[i][1]记录以i-2为结尾的子串加v[i]的子串最大长度
        int ans = 0;
        _for(i,0,n) {
            dp[i][0] = max(dp[i][0], 1);
            if(v[i] < v[i+1]){
                dp[i+1][0] = max(dp[i+1][0], dp[i][0]+1);
                dp[i+1][1] = max(dp[i+1][1], dp[i][1]+1);
            }
            if(v[i] < v[i+2]) 
                dp[i+2][1] = max(dp[i+2][1], dp[i][0]+1);
            ans = max(ans, max(dp[i][0], dp[i][1]));
    //cout << " i = " << i << " dp[i][0] = " << dp[i][0] << "  dp[i][1] = " << dp[i][1] << endl;
        }cout << ans << '
    ';
        return;
    }
    View Code
    void taskE(){
        int n; cin >> n;
        vector<int> v(n+1, 0), dp(n+1, -1);
        int odd = 0, even = 0;
        _rep(i,1,n) cin >> v[i],  v[i]&1 ? odd++ : even++;
        if(!odd || !even) {
            _for(i,1,n) cout << "-1 "; cout << "-1
    ";
            return;
        }
        queue<int> q;
        vector<vector<int> > g(n+1);
        _rep(i,1,n) {
            int lf = i-v[i], rg = i+v[i];
            if(lf > 0 && lf <= n) {
                if(v[lf]%2 != v[i]%2) dp[i] = 1;
                g[lf].push_back(i);
            }
            if(rg <= n) {
                if(v[rg]%2 != v[i]%2) dp[i] = 1;
                g[rg].push_back(i);
            }
            if(dp[i]==1) q.push(i);
        }
        
        while(!q.empty()){
            int x = q.front(); q.pop();
            for(int it : g[x]){
                if(dp[it] == -1 && v[it]%2 == v[x]%2)
                {
                    dp[it] = dp[x]+1;
                    q.push(it);
                }
            }
        }
        _for(i,1,n) cout << dp[i] << " "; cout << dp[n] << "
    ";
        return;
    }
    const int N = 202;
    const int INF = 1e9;
    int dp[N][N][2*N];
    pair<pair<int, int>, pair<int, char> > p[N][N][2*N];
    //dp[i][j][bal]记录贪心 s的位置i 和 t的位置j, bal为括号序列的已有 (数量 -  )的数量, 规则括号序列bal为0
    void taskF(){
        string s,t; cin >> s >> t;
        int n = s.size(), m = t.size();
        _rep(i,0,n) _rep(j,0,m) _for(bal,0,2*N) dp[i][j][bal] = INF;
        dp[0][0][0] = 0;
        
        _rep(i,0,n) _rep(j,0,m) _for(bal,0,2*N) {
            if(dp[i][j][bal] == INF) continue;
    
            int nxi = i + (i<n && s[i]=='(');
            int nxj = j + (j<m && t[j]=='(');
            if(bal+1<2*N && dp[nxi][nxj][bal+1] > dp[i][j][bal]+1) {
                dp[nxi][nxj][bal+1] = dp[i][j][bal]+1;
                p[nxi][nxj][bal+1] = make_pair(make_pair(i, j), make_pair(bal, '('));
            }
    
            nxi = i + (i<n && s[i]==')');
            nxj = j + (j<m && t[j]==')');
            if(bal>=1 && dp[nxi][nxj][bal-1] > dp[i][j][bal]+1) {
                dp[nxi][nxj][bal-1] = dp[i][j][bal]+1;
                p[nxi][nxj][bal-1] = make_pair(make_pair(i, j), make_pair(bal, ')'));
            }
        }
    
        int cbal = 0;
        _for(bal,0,2*N) if(dp[n][m][bal]+bal < dp[n][m][cbal]+cbal) cbal = bal;//最小前缀串长度 加上需要的后缀串长度
    
        string res = string(cbal, ')');
    //cout << " res =  " << res << "  
    ";
        //因为dp[n][m][0]从后开始加  所以需要先加后缀串 再加上p中记录的增加的( ), 最后倒一下
        int ci = n, cj = m;
        while(ci > 0 || cj > 0 || cbal) {//
            int nci = p[ci][cj][cbal].first.first;
            int ncj = p[ci][cj][cbal].first.second;
            int ncbal = p[ci][cj][cbal].second.first;
            res += p[ci][cj][cbal].second.second;
            ci = nci, cj = ncj, cbal = ncbal;
        }
    //cout << "res = " << res << '
    ';
        reverse(res.begin(), res.end());
        cout << res << '
    ';
        return;
    }
    int main(){
        //taskA();
        //taskB();
        //taskC();
      //taskD();
      //taskE();
      //taskF(); return 0; }
  • 相关阅读:
    20190912
    20190825
    20190818
    20190811
    20190804
    数据结构与算法之顺序表
    数据结构与算法之顺序表
    数据结构与算法之单链表
    数据结构与算法之循环双链表
    数据结构与算法之循环单链表
  • 原文地址:https://www.cnblogs.com/163467wyj/p/12037767.html
Copyright © 2011-2022 走看看