• 2019牛客暑期多校训练营(第七场)


    题号 标题 已通过代码 题解/讨论 通过率 团队的状态
    A String 点击查看 进入讨论 561/3518 通过
    B Irreducible Polynomial 点击查看 进入讨论 724/2269 通过
    C Governing sand 点击查看 进入讨论 383/2052 通过
    D Number 点击查看 进入讨论 955/1462 通过
    E Find the median 点击查看 进入讨论 82/968 未通过
    F Energy stones 点击查看 进入讨论 15/131 未通过
    G Make Shan Happy 点击查看 进入讨论 2/28 未通过
    H Pair 点击查看 进入讨论 92/239 未通过
    I Chessboard 点击查看 进入讨论 17/82 未通过
    J A+B problem 点击查看 进入讨论 1023/1843 通过
    K Function 点击查看 进入讨论 8/49 未通过

    A

    知识点:字符串最小表示法

    对于开头位置为 i 的串,暴力从后往前找最远的 j 使得 s[i...j] 为其自己的最小表示

    ps: 题解里面写的做法没搞出来,见很多大佬不到5ms就过了

    关于最小表示:OI Wiki

    #include <bits/stdc++.h>
    using namespace std;
    int T,n;
    int num;
    char s[220];
    char t[500];
    //判断s[l...r] 是否为自己的最小表示
    bool ok(int l,int r){
        int n = r - l + 1;
        for(int i=1;i<=n;i++)t[i] = s[l + i - 1];
        for(int i=1;i<=n;i++)t[n+i] = s[l + i - 1];
        int i=1,j=2,k;
        while(i<=n && j <= n){
            for(k = 0; k <= n && t[i+k] == t[j+k];k++);
                if(k == n)break;
            if(t[i+k] > t[j+k]){
                i = i + k + 1;
                if(i == j)i++;
            }
            else{
                j = j + k + 1;
                if(i == j)j++;
            }
        }
        int ans = min(i,j);
        for(int i=0;i<n;i++){
            if(t[ans+i] == s[l+i])continue;
            else return false;
        }
        return true;
    }
    void print(int l,int r){
        for(int i=l;i<=r;i++)printf("%c",s[i]);
        printf(" ");
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%s",s+1);
            n = strlen(s+1);
            num = 0;
            for(int i=1;i<=n;){
                for(int j=n;j>=i;j--){
                    if(i == j || ok(i,j)){
                        print(i,j);
                        i = j+1;
                    }
                }
            }
            puts("");
        }
        return 0;
    }
    

    B

    结论:实数域不可拆分多项式只有两种:一次多项式和二次的((b^2<4ac))

    #include <bits/stdc++.h>
    using namespace std;
    int T;
    int n;
    long long a[1005];
    int main(){
        scanf("%d", &T);
        while(T--){
            scanf("%d", &n);
            for(int i = 0; i <= n; i++){
                scanf("%lld", &a[i]);
            }
            if(n >= 3){
                puts("No");
            }
            else if(n <= 1){
                puts("Yes");
            }
            else{
                if(a[1] * a[1] - 4 * a[0] * a[2] < 0){
                    puts("Yes");
                }
                else{
                    puts("No");
                }
            }
        }
        return 0;
    }
    

    C

    按照高度从小到大排序,然后枚举当前高度作为最高高度,然后比它高得树都要砍掉,比它小得树里面挑一些数量的树(按照价格从小到大考虑)使得剩余数量小于等于当前枚举的最高高度的树的数量。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll cost[205];
     
    struct node {
        int h, c, p;
    }E[100005];
     
    bool cmp(node A, node B) {
        return A.h > B.h;
    }
    ll suf[100005];
     
    int main() {
        int n;
        while(~scanf("%d", &n)) {
            ll ans = 0;
            memset(cost, 0, sizeof(cost));
            for(int i = 1; i <= n; i++) {
                scanf("%d%d%d", &E[i].h, &E[i].c, &E[i].p);
                cost[E[i].c] += 1LL * E[i].p;
                ans += 1LL * E[i].c * E[i].p;
            }
            sort(E + 1, E + 1 + n, cmp);
            suf[n] = 1LL * E[n].p;
            for(int i = n - 1; i >= 1; i--) suf[i] = suf[i + 1] + 1LL * E[i].p;
     
            ll pre = 0;
            for(int i = 1; i <= n; i++) {
                int j;
                ll num = 0;    //同一高度的树
                ll cutx = 0;   //砍掉同一高度的花费
                bool tail = true;
                ll tmp = suf[i];
                for(j = i; j <= n; j++) {
                    if(E[j].h == E[i].h) {
                        cutx += 1LL * E[j].p * E[j].c;
                        num += 1LL * E[j].p;
                        tmp -= 1LL * E[j].p;
                        cost[E[j].c] -= 1LL * E[j].p;
                    } else {
                        tail = false;
                        i = j - 1;
                        break;
                    }
                }
                if(tail) i = n;
     
                if(tmp < num) tmp = 0;
                else tmp = tmp - num + 1;
                ll cut = 0;
                for(int j = 1; j <= 200; j++) {
                    if(cost[j] >= tmp) {
                        cut += 1LL * j * tmp;
                        tmp = 0;
                        break;
                    } else {
                        cut += 1LL * j * cost[j];
                        tmp -= cost[j];
                    }
                }
                ll ccc = cut + pre;
                ans = min(ans, ccc);
                pre += cutx;
                if(pre >= ans) break;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    D

    如果n的长度大于等于p,则先输出p然后在p后面补0,否则答案不存在

    #include <bits/stdc++.h>
    using namespace std;
    int n,p;
    int calc(int x){
        int res = 0;
        while(x)res++,x/=10;
        return res;
    }
    int main(){
        scanf("%d%d",&n,&p);
        int len = calc(p);
        if(n >= len){
            printf("%d",p);
            for(int i=len;i<n;i++)printf("0");
            puts("");return 0;
        }
        else puts("T_T");
        return 0;
    }
    

    J

    #include <bits/stdc++.h>
     
    using namespace std;
     
    int T;
     
    char a[100];
    char b[100];
     
    char c[105];
     
    int main(){
        scanf("%d", &T);
        while(T--){
            memset(c, 0, sizeof(c));
     
            scanf("%s%s", a, b);
            reverse(a, a + strlen(a));
            reverse(b, b + strlen(b));
            long long aa, bb;
            aa = bb = 0;
            for(int i = 0; a[i]; i++){
                aa *= 10;
                aa += a[i] - '0';
            }
            for(int i = 0; b[i]; i++){
                bb *= 10;
                bb += b[i] - '0';
            }
            long long ans = aa + bb;
             
            int cnt = 0;
            bool flag = false;
            for(int i = 0; ans > 0; i++){
                c[i] = '0' + (ans % 10);
                 
                if(!flag && c[i] != '0'){
                    flag = true;
                    cnt = i;
                }
     
                ans /= 10;
            }
     
            if(!flag){
                puts("0");
            }
            else{
                printf("%s
    ", c + cnt);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    json 总结
    Django---admin简单功能
    Django---Models
    Django---Template(模板)
    Django---URL、Views
    Django---定义、MVC和MTV模式、命令行工具、配置文件settings
    必学算法
    一个虚拟社交公司的融资历程
    分布式系统,本文引用“courage”的博客
    mysql语句
  • 原文地址:https://www.cnblogs.com/1625--H/p/11323153.html
Copyright © 2020-2023  润新知