• kickstart_Round C 2020


    题目链接

    做题情况:100% + 100% + 50% + 0%, 43分, 1935名

    第一题:m序列的个数(连续m个递减且最后一个为1),n<2e5

    思路:用dp记录递减序列的长度

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5 +10;
    const int INF = 0x3f3f3f3f;
    int n, k, a[maxn], dp[maxn];
    
    int main()
    {
        int T, kase = 0;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d", &n, &k);
            for(int i = 0;i < n;i++)  scanf("%d", &a[i]);
            for(int i = 0;i < n;i++) dp[i] = -INF;
            for(int i = n-1;i >= 0;i--)
            {
                if(a[i] == a[i+1]+1)  dp[i] = dp[i+1]+1;
                if(a[i] == 1)  dp[i] = 1;
            }
            //for(int i = 0;i < n;i++)  printf("%d ", dp[i]);
            //printf("
    ");
            int ans = 0;
            for(int i = 0;i < n;i++)
                if(dp[i] == k)  ans++;
            printf("Case #%d: %d
    ", ++kase, ans);
        }
        return 0;
    }
    View Code

    第二题:给定一个字符矩阵,判断能否从底到上堆积。(字符种类数不会超过26)

    思路:统计有哪些种类的字符,dfs枚举字符的排列顺序。剪枝:每次都check(path)

    #include<bits/stdc++.h>
    using namespace std;
    
    char maze[35][35];
    char poly[30];
    int cnt;
    bool vis[30];
    int r, c;
    int kase;
    
    bool check(vector<int>& path)
    {
        char tmaze[35][35];
        for(int i = 0;i < r;i++)
            for(int j = 0;j < c;j++) tmaze[i][j] = maze[i][j];
        int n = path.size();
        for(int k = 0;k < n;k++)
        {
            for(int i = r-1;i >= 0;i--)
                for(int j = 0;j < c;j++)
                {
                    if(tmaze[i][j] == poly[path[k]])
                    {
                        if(i == r-1 || tmaze[i+1][j] == 'a')
                        {
                            tmaze[i][j] = 'a';
                        }
                        else  return false;
                    }
                }
        }
        return true;
    }
    
    bool dfs(int cur, vector<int>& path)  // 考察到第cur个
    {
        if(cur == cnt)
        {
            if(check(path))
            {
                printf("Case #%d: ", ++kase);
                for(int i = 0;i < cnt;i++)
                {
                    printf("%c", poly[path[i]]);
                }
                printf("
    ");
                return true;
            }
            else  return false;
        }
        if(!check(path))  return false;
        for(int i = 0;i < cnt;i++)
        {
            if(!vis[i])
            {
                vis[i] = true;
                path.push_back(i);
                if(dfs(cur+1, path)) return true;
                vis[i] = false;
                path.pop_back();
            }
        }
        return false;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            //int r, c;
            scanf("%d%d", &r, &c);
            for(int i = 0;i < r;i++)
                scanf("%s", maze[i]);
            set<int>s;
            s.clear();
            cnt = 0;
            for(int i = 0;i < r;i++)
                for(int j = 0;j < c;j++)
                {
                    char c = maze[i][j];
                    if(s.count(c) == 0)
                    {
                        s.insert(c);
                        poly[cnt++] = c;
                    }
                }
    
            for(int i = 0;i < 30;i++)  vis[i] = false;
            vector<int>path;
            if(!dfs(0, path))
            {
                printf("Case #%d: -1
    ", ++kase);
            }
        }
        return 0;
    }
    View Code

    第三题:求完美子序列(和为完全平方数的序列)的个数,N<1e5

    思路:把前缀和放到map中,枚举每个位置,再枚举可能出现的平方数。

    #include<bits/stdc++.h>
    using namespace std;
    using LL = long long;
    constexpr int maxn = -1;
    void work(){
        int N;
        cin >> N;
        int S = 0, MS = 0;
        unordered_map<int, int> mp;
        mp[S] += 1;
        LL ans = 0;
        for(int i = 1, A; i <= N; i += 1){
            cin >> A;
            S += A;
            for(int j = 0;; j += 1){
                int T = S - j * j;
                if(T < MS) break;
                if(mp.count(T)) ans += mp[T];
            }
            MS = min(MS, S);
            mp[S] += 1;
        }
        cout << ans << "
    ";
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
        int T;
        cin >> T;
        for(int t = 1; t <= T; t += 1){
            cout << "Case #" << t << ": ";
            work();
        }
        return 0;
    }
    View Code

    第四题:一个序列,两种操作:查询和修改

    思路:一看就是线段树,但是不会做。(这里记录一下大佬的代码,有空学习一下)

    #include<bits/stdc++.h>
    using namespace std;
    using LL = long long;
    constexpr int maxn = 200000;
    #define ls (v << 1)
    #define rs (ls | 1)
    #define tm ((tl + tr) >> 1)
    LL A[maxn + 1];
    struct Node{
        LL ans, sum, size;
        Node operator + (const Node& node)const{
            Node res;
            res.size = size + node.size;
            if(size & 1) res.sum = sum - node.sum;
            else res.sum = sum + node.sum;
            if(size & 1) res.ans = ans - node.ans - size * node.sum;
            else res.ans = ans + node.ans + size * node.sum;
            return res; 
        }
    }T[maxn << 2];
    void build(int v, int tl, int tr){
        if(tl == tr){
            T[v].size = 1;
            T[v].ans = T[v].sum = A[tm];
        }
        else{
            build(ls, tl, tm);
            build(rs, tm + 1, tr);
            T[v] = T[ls] + T[rs];
        }
    }
    void update(int v, int tl, int tr, int x, int V){
        if(tl == tr)
            T[v].ans = T[v].sum = V;
        else{
            if(x <= tm) update(ls, tl, tm, x, V);
            else update(rs, tm + 1, tr, x, V);
            T[v] = T[ls] + T[rs];
        }
    }
    Node query(int v, int tl, int tr, int L, int R){
        if(tl >= L and tr <= R) return T[v];
        if(R <= tm) return query(ls, tl, tm, L, R);
        if(L > tm) return query(rs, tm + 1, tr, L, R);
        return query(ls, tl, tm, L, R) + query(rs, tm + 1, tr, L, R);
    }
    void work(){
       int N, Q;
       cin >> N >> Q;
       for(int i = 1; i <= N; i += 1) cin >> A[i];
       build(1, 1, N);
       LL ans = 0;
       for(int i = 1; i <= Q; i += 1){
           string s;
           cin >> s;
           if(s == "U"){
               LL X, V;
               cin >> X >> V;
               update(1, 1, N, X, V);
           }
           else{
               int L, R;
               cin >> L >> R;
               //cout << query(1, 1, N, L, R).ans << "
    ";
               ans += query(1, 1, N, L, R).ans;
           }
       }
       cout << ans << "
    ";
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
        int T;
        cin >> T;
        for(int t = 1; t <= T; t += 1){
            cout << "Case #" << t << ": ";
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Spoj-DWARFLOG Manipulate Dwarfs
    Spoj-DRUIDEOI Fata7y Ya Warda!
    LightOJ1106 Gone Fishing
    LightOJ1125 Divisible Group Sums
    hdu5396 Expression
    cf715B Complete The Graph
    cf601A The Two Routes
    cf602B Approximating a Constant Range
    cf602A Two Bases
    认证方式
  • 原文地址:https://www.cnblogs.com/lfri/p/12907579.html
Copyright © 2020-2023  润新知