• 《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
  • 相关阅读:
    690. 员工的重要性
    91. 解码方法
    153. 寻找旋转排序数组中的最小值
    81. 搜索旋转排序数组 II
    33. 搜索旋转排序数组
    80. 删除有序数组中的重复项 II
    5708. 统计一个数组中好对子的数目
    高精度除法
    易闻app
    2021.4.13
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15635036.html
Copyright © 2020-2023  润新知