• Codeforces_Round_547 (Div. 3)题解


    题目链接

    传送门

    A题

    题目

    题意

    给你两个正整数(n)(m),然后你可以进行无数次操作(每次操作可以将(n)扩大两倍,或者扩大三倍),问你是否能够得到(m)

    代码实现如下

    n, m = map(int, input().split())
    if m % n == 0:
        num = 0
        m //= n
        while(m % 2 == 0):
            m //= 2
            num = num + 1
        while(m % 3 == 0):
            m //= 3
            num = num + 1
        if(m == 1):
            print(num)
        else:
            print(-1)
    else:
        print(-1)
    

    B题

    题目


    题意

    给你一个长度为(n)(01)串进行无限循环,问你连续最长的(1)有多长。

    思路

    将这个(01)串复制一次,然后找连续最长的(1)就行。

    代码实现如下

    n = eval(input())
    a = list(map(int, input().split()))
    a.extend(a)
    cnt = 0
    l = -1
    for i in range(2*n):
        if(a[i] == 1):
            if(l == -1):
                l = i
                cnt = max(cnt, 1)
            else:
                cnt = max(cnt, i - l + 1)
        else:
            l = -1
    print(cnt)
    

    C题

    题目

    题意

    有一个长为(1~n)的排列(a_i),现在给你相邻两项的差(p_i),要你重新构造这个排列。

    思路

    我们通过计算可以发现(a_2=a_1+p_1,a_3=a_1+p_1+p_2,a_n=a_1+p_1+p_2+...+p_{n-1}),然后我们知道(sum_{i=1}^{k}p_i)最大对应的那个(a_i)一定是(n),因此我们一减就可以得到(a_1),然后剩下的也都可以通过前面说的那些等式构造出来~

    代码实现如下

    n = eval(input())
    a = list(map(int,input().split()))
    p = [0]
    for i in range(0,n-1):
      p.append(p[-1]+a[i])
    mx = max(p)
    ans = []
    ans.append(n-mx)
    for i in range(1,n):
      ans.append(ans[0]+p[i])
    if set(range(1,n+1))==set(ans):
      print(*ans)
    else:
      print(-1)
    

    D题

    题目


    题意

    给你两个字符串(s)(t),问这两个字符串的最大匹配度是多少。
    匹配规则为:

    1.相同字母进行匹配;
    2.字符和'?'进行匹配。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> piL;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("in","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int maxn = 150000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n;
    char s[maxn], t[maxn];
    vector<int> l[30], r[30], lp, rp;
    vector<pii> ans;
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d", &n);
        scanf("%s%s", s, t);
        for(int i = 0; i < n; ++i) {
            if(s[i] == '?') {
                lp.push_back(i+1);
            } else {
                int x = s[i] - 'a';
                l[x].push_back(i+1);
            }
            if(t[i] == '?') {
                rp.push_back(i+1);
            } else {
                int x = t[i] - 'a';
                r[x].push_back(i+1);
            }
        }
        for(int i = 0; i < 26; ++i) {
            int lsz = (int)l[i].size(), rsz = (int)r[i].size();
            int lpsz = (int)lp.size(), rpsz = (int)rp.size();
            while(lsz >= 1 && rsz >= 1) {
                ans.push_back({l[i][lsz-1], r[i][rsz-1]});
                l[i].pop_back();
                r[i].pop_back();
                lsz--, rsz--;
            }
            while(lsz >= 1 && rpsz >= 1) {
                ans.push_back({l[i][lsz-1], rp[rpsz-1]});
                l[i].pop_back();
                rp.pop_back();
                lsz--, rpsz--;
            }
            while(rsz >= 1 && lpsz >= 1) {
                ans.push_back({lp[lpsz-1], r[i][rsz-1]});
                r[i].pop_back();
                lp.pop_back();
                rsz--, lpsz--;
            }
        }
        int lpsz = (int)lp.size(), rpsz = (int)rp.size();
        while(lpsz && rpsz) {
            ans.push_back({lp[lpsz-1], rp[rpsz-1]});
            lp.pop_back();
            rp.pop_back();
            lpsz--, rpsz--;
        }
        printf("%d
    ", (int)ans.size());
        for(auto x : ans) {
            printf("%d %d
    ", x.first, x.second);
        }
        return 0;
    }
    

    E题

    题目

    题意

    有一只血量为(H)的怪物,每一轮有(n)个回合,每一回合血量的变化为(d_i),每一轮的变化情况都和上一轮一样,问怪物在第几回合死亡。

    思路

    暴力,不太擅长这种题……

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> piL;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("in","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int maxn = 1e6 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n;
    int d[maxn];
    LL H, sum;
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%lld%d", &H, &n);
        LL mx = inf;
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &d[i]);
            sum += d[i];
            if(sum < 0) mx = min(mx, sum);
        }
        if(sum >= 0) {
            for(int i = 1; i <= n; ++i) {
                H += d[i];
                if(H <= 0) {
                    printf("%d
    ", i);
                    return 0;
                }
            }
            printf("-1
    ");
        } else {
            LL ans = 0;
            for(int i = 1; i <= n; ++i) {
                H += d[i];
                if(H <= 0) {
                    printf("%d
    ", i);
                    return 0;
                }
            }
            ans += n;
            sum = -sum;
            ans += H / sum * n;
            H %= sum;
            if(mx != inf) {
                mx = -mx;
                ans -= (mx + sum - 1) / sum * n;
                H += (mx + sum - 1) / sum * sum;
            }
            while(H > 0) {
                for(int i = 1; i <= n; ++i) {
                    H += d[i];
                    if(H <= 0) {
                        ans += i;
                        break;
                    }
                }
                if(H > 0) ans += n;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    F题

    题目


    题意

    给你(n)个数,要你选择不相交的(k)个区间,使得这(k)个区间的和相同,最大化k。

    思路

    由于(n)很小,我们可以先暴力以(i)为左端点(j)为右端点这段区间的和,然后用一个(vector)来存下这个和对应的所有区间,然后对每个和的所有区间进行贪心取即可(贪心入门经典题)。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> piL;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define x first
    #define y second
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("in","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int maxn = 2e6 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n;
    int a[maxn], vis[maxn];
    LL sum[maxn];
    vector<LL> s;
    vector<pii> v[maxn], seg;
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1] + a[i];
            for(int j = 1; j <= i; ++j) {
                s.push_back(sum[i] - sum[j-1]);
            }
        }
        sort(s.begin(), s.end());
        s.erase(unique(s.begin(), s.end()), s.end());
        int sz = s.size();
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= i; ++j) {
                int x = sum[i] - sum[j-1];
                int p = lower_bound(s.begin(), s.end(), x) - s.begin();
                v[p].push_back({i, j});
            }
        }
        for(int i = 0; i < sz; ++i) sort(v[i].begin(), v[i].end());
        int ans = 0;
        for(int i = 0; i < sz; ++i) {
            int las = 0, cnt = 0;
            for(int j = 0; j < v[i].size(); ++j) vis[j] = 0;
            for(int j = 0; j < v[i].size(); ++j) {
                if(v[i][j].y > las) {
                    cnt++;
                    vis[j] = 1;
                    las = v[i][j].x;
                }
            }
            if(cnt > ans) {
                seg.clear();
                ans = cnt;
                for(int j = 0; j < v[i].size(); ++j) {
                    if(vis[j]) {
                        seg.push_back({v[i][j]});
                    }
                }
            }
        }
        printf("%d
    ", ans);
        for(auto x : seg) {
            printf("%d %d
    ", x.y, x.x);
        }
        return 0;
    }
    

    G题

    题目


    题意

    给你一棵树,需要将树进行染色,可以有(k)个结点(称为特殊点)使得它所连接的边颜色相同,其他的(n-k)个结点连接的边的颜色不能相同,要你最小化颜色数。

    思路

    要使得颜色数最少,我们很容易可以知道度最大的(k)个结点是特殊点(我们可以知道颜色数(equiv)非特殊点中度最大的结点的度,因此要想最小化颜色数,就要最小化非特殊点中度最大的结点的度),剩下的dfs进行染色即可。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> piL;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("in","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int maxn = 1e6 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, k, tot, ans;
    int in[maxn], head[maxn], vis[maxn], c[maxn];
    
    struct edge {
        int v, next;
    }ed[maxn];
    
    void add(int u, int v) {
        ed[tot].v = v;
        ed[tot].next = head[u];
        head[u] = tot++;
    }
    
    void dfs(int u, int p, int pp) {
        int cnt = 0;
        for(int i = head[u]; ~i; i = ed[i].next) {
            int v = ed[i].v;
            if(v == p) continue;
            if(vis[u]) c[i] = (pp == 0 ? 1 : pp);
            else {
                cnt++;
                if(cnt == pp) cnt++;
                c[i] = cnt;
            }
            dfs(v, u, c[i]);
        }
        ans = max(ans, max(1, cnt));
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d%d", &n, &k);
        int u, v;
        for(int i = 1; i <= n; ++i) head[i] = -1;
        for(int i = 1; i < n; ++i) {
            scanf("%d%d", &u, &v);
            add(u, v); add(v, u);
            in[u]++, in[v]++;
        }
        priority_queue<pii> q;
        for(int i = 1; i <= n; ++i) {
            q.push({in[i], i});
        }
        int cnt = 0;
        while(cnt < k) {
            vis[q.top().second] = 1;
            q.pop();
            cnt++;
        }
        dfs(1, 0, 0);
        printf("%d
    ", ans);
        for(int i = 0; i < tot; ++i) {
            if(c[i] == 0) continue;
            printf("%d ", c[i]);
        }
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    Python学习 之 文件
    Python学习 之 对内存的使用(浅拷贝和深拷贝)
    Python学习 之 爬虫
    Python学习 之 正则表达式
    为何现在的网页广告都是有关你搜索或者购买过的商品 2015-08-22 22:06 1534人阅读 评论(35) 收藏
    Junit使用注意点
    用递归方式在JSON中查找对象
    利用StringBuffer来替换内容
    使用ant时 出现 java.lang.OutOfMemoryErro r: Java heap space的解决办法
    python-re使用举例
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11162350.html
Copyright © 2020-2023  润新知