zoukankan      html  css  js  c++  java
  • 《Educational Codeforces Round 118 (Rated for Div. 2)》

    A题写炸了。

    A:一开始写了个字符串没算复杂度T了,实际上从高到低判断即可。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int a[N],b[N];
    int len(int x) {
        int len = 0;
        while(x != 0) a[++len] = x % 10,x /= 10;
        reverse(a + 1,a + len + 1);
        return len;
    }
    int glen2(int x) {
        int len = 0;
        while(x != 0) b[++len] = x % 10,x /= 10;
        reverse(b + 1,b + len + 1);
        return len;
    }
    void solve() {
        int x,p;cin >> x >> p;
        int x2,p2;cin >> x2 >> p2;
        int le1 = len(x),le2 = glen2(x2);
        int len1 = le1 + p,len2 = le2 + p2;
        if(len1 > len2) printf(">\n");
        else if(len1 < len2) printf("<\n");
        else {
            if(le1 == le2) {
                if(x == x2) printf("=\n");
                else printf("%c\n",x > x2 ? '>' : '<');
            }
            else if(le1 > le2) {
                int f = 0;
                for(int i = 1;i <= min(le1,le2);++i) {
                    if(a[i] > b[i]) {f = 1;printf(">\n");break;}
                    else if(a[i] < b[i]) {f = 1;printf("<\n");break;}
                }
                if(f == 0) {
                    int ff = 0;
                    for(int i = le2 + 1;i <= le1;++i) if(a[i] != 0) {ff = 1;}
                    printf("%c\n",ff ? '>' : '=');
                }
            }
            else {
                int f = 0;
                for(int i = 1;i <= min(le1,le2);++i) {
                    if(a[i] > b[i]) {f = 1;printf(">\n");break;}
                    else if(a[i] < b[i]) {f = 1;printf("<\n");break;}
                }
                if(f == 0) {
                    int ff = 0;
                    for(int i = le1 + 1;i <= le2;++i) if(b[i] != 0) {ff = 1;}
                    printf("%c\n",ff ? '<' : '=');
                }
            }
        }
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
      //  system("pause");
        return 0;
    }
    View Code

    B:每个数和最小的操作必定 < 最小的

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int a[N];
    vector<pii> ans;
    int pos[M];
    void solve() {
        int n;scanf("%d",&n);
        rep(i,1,n) scanf("%d",&a[i]),pos[a[i]] = i;
        int up = n / 2;
        sort(a + 1,a + n + 1);
        for(int i = 2;i <= up + 1;++i) printf("%d %d\n",a[i],a[1]);
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
        //system("pause");
        return 0;
    }
    View Code

    C:比较经典的二分了

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int n,a[N];
    LL h;
    bool check(LL x) {
        LL r = a[1] + x - 1,de = 0;
        for(int i = 2;i <= n;++i) {
            if(a[i] > r) de += x;
            else de += a[i] - a[i - 1];
            r = a[i] + x - 1;
        }
        de += x;
       // printf("x is %lld de is %lld\n",x,de);
        return de >= h;
    }
    void solve() {
        scanf("%d %lld",&n,&h);
        rep(i,1,n) scanf("%d",&a[i]);
        LL L = 1,r = h,ans = h;
        while(L <= r) {
            LL mid = (L + r) >> 1;
            if(check(mid)) ans = mid,r = mid - 1;
            else L = mid + 1;
        }
        printf("%lld\n",ans);
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
        //system("pause");
        return 0;
    }
    View Code

    D:这题比E要难挺多感觉。

    一开始推了个错的dp。

    首先,我们需要对序列进行判断,假设当前为111 222 333.

    那么这时候我们在序列后面 + 4 = 111 222 333 4 - 保持上升序列

    + 1,2显然都不合法,+ 5满足这时序列变为111 222 333 5。

    当序列为111 222 333 5时,我们在尾部能加得元素就只有3,5其他加入都不满足。

    所以我们插入的序列一定是一个上序序列或者断开过一截的上升序列。

    考虑dp解决。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 5e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 998244353;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int n;
    LL dp[N][3],tmp[3];//0 - i作为最大值且没有断裂,1 - i作为最大值发生断裂,2 - i作为次大值发生断裂
    void solve() {
        scanf("%d",&n);
        rep(i,0,n + 2) rep(j,0,2) dp[i][j] = 0;
        rep(i,1,n) {
            int x;scanf("%d",&x);
            memset(tmp,0,sizeof(tmp));
            tmp[0] = dp[x][0];
            if(x > 0) tmp[0] = ADD(tmp[0],dp[x - 1][0]);
            else tmp[0] = ADD(tmp[0],1);
            
            tmp[1] = ADD(tmp[1],dp[x][1]);
            if(x > 1) tmp[1] = ADD(tmp[1],ADD(dp[x - 2][0],dp[x - 2][2]));
            else if(x == 1) tmp[1] = ADD(tmp[1],1);
    
            tmp[2] = ADD(tmp[2],dp[x][2]);
            tmp[2] = ADD(tmp[2],dp[x + 2][1]);
            dp[x][0] = ADD(dp[x][0],tmp[0]);
            dp[x][1] = ADD(dp[x][1],tmp[1]);
            dp[x][2] = ADD(dp[x][2],tmp[2]);
          //  printf("in %d dp[0] is %lld dp[1] is %lld d[2] is %lld\n",i,tmp[0],tmp[1],tmp[2]);
        }
        LL ans = 0;
        rep(i,0,n) rep(j,0,2) {
            //if(dp[i][j] != 0) printf("dp[%d][%d] is %lld\n",i,j,dp[i][j]);
            ans = ADD(ans,dp[i][j]);
        }
        printf("%lld\n",ans);
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
       // system("pause");
        return 0;
    }
    /*
    30
    7
    1 3 2 3 0 0 1
    9
    3 1 2 1 0 2 0 3 0
    */
    View Code

    E:

    这题其实不难,很显然从L开始搜,这时我们会遇到一个情况,它处于可以走到L的一个块的旁边,但是现在我们去判断。

    这个块还不能走到L,其实我们并不需要管,因为当这个块能走到L时,肯定会被它旁边另外一个新的能走到L的更新成功。

    所以一次bfs就能解决问题。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<char,int> pii;
    const int N = 1e6 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 998244353;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    vector<pii> vec[N];
    int n,m,d[4][2] = {1,0,-1,0,0,1,0,-1};
    bool ishav(int i,int j) {
        if(i >= 0 && i < n && j >= 0 && j < m && vec[i][j].first != '#' && vec[i][j].second != 1) return true;
        else return false; 
    }
    bool check(int i,int j) {
        if(i >= 0 && i < n && j >= 0 && j < m && vec[i][j].first == '.' && vec[i][j].second != 1) return true;
        else return false; 
    }
    struct Node{int x,y;};
    void bfs(int x,int y) {
        queue<Node> Q;
        vec[x][y].second = 1;
        Q.push(Node{x,y});
        while(!Q.empty()) {
            Node q = Q.front();
            Q.pop();
            rep(i,0,3) {
                int px = q.x + d[i][0],py = q.y + d[i][1];
                if(ishav(px,py)) {
                    int cnt = 0;
                    rep(j,0,3) if(check(px + d[j][0],py + d[j][1])) cnt++;
                   // printf("px is %d py is %d cnt is %d\n",px,py,cnt);
                    if(cnt <= 1) {
                        vec[px][py].second = 1;
                        Q.push(Node{px,py});
                    }
                }
            }
        }
    }
    void solve() {
        scanf("%d %d",&n,&m);
        int edi,edj;
        rep(i,0,n - 1) {
            string s;cin >> s;
            rep(j,0,m - 1) {
                if(s[j] == 'L') edi = i,edj = j;
                vec[i].push_back(pii{s[j],0});
            }
        }
        bfs(edi,edj);
        rep(i,0,n - 1) {
            rep(j,0,m - 1) {
                if(vec[i][j].second != 1 || vec[i][j].first == 'L') printf("%c",vec[i][j].first);
                else printf("+");
            }
            printf("\n");
        }
        rep(i,0,n - 1) vec[i].clear();
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
     //   system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    167. 两数之和 II
    14. 最长公共前缀
    28. 实现strStr()
    118. 杨辉三角
    54. 螺旋矩阵
    498. 对角线遍历
    66. 加一
    747. 至少是其他数字两倍的最大数
    34. 在排序数组中查找元素的第一个和最后一个位置
    164. 寻找峰值
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15635036.html
Copyright © 2011-2022 走看看