• xjoi contest1(cf1084原题)


    学军奋斗组训练contest1

    T1:The Fair Nut and Elevator

    这题说实在的还是折腾了我不少时间,因为本蒟蒻可怜的英语能力。

    题意:

    有N(n <= 100)个楼层,每层楼里住着ai 个人,其中有一台奇怪的电梯管理着这栋楼上上下下。它固定停在某一层(由你决定),当有人要使用时依次到达起点和终点最后回来(每个人只会从一楼到自己的,或者从自己的到1层,每天上下班共一个来回),才会进行下一轮工作,且同时只会运输一个人。(真省电。。。。。。)为了省电,于是想问你当电梯停在任意楼层时,最少需要跑多少楼层。

    思路的话,直接暴力枚举电梯固定停的楼层,在再计算,n2无压力水过。

    Select Code
    #include<bits/stdc++.h>
    using namespace std;
    int a[101];
    int main()
    {
        int n;
        cin >> n;
        for(int i = 1;i <= n;i++)
        {
            int x;
            scanf("%d",&x);
            a[i] = x;
        }
        int ans = 1000000001;
        for(int i = 1;i <= n;i++)
        {
            int sum = 0;
            for(int j = 1;j <= n;j++)
            {
                sum += 2*a[j]*(abs(j-i)+j-1+i-1);
            }
            ans = min(ans,sum);
        }
        cout << ans; 
        return 0;
    }

    T2:Kvass and the Fair Nut

     很水的二分题,但是我考试时打挂了。没办法,只能糊式子。

    题意:

    有n(n <= 103)杯水,其中第i杯水有ai(a<= 109)份水,你先在需要从这些杯子中倒出总共s(s <= 1012)份的水,使含有最少水的杯子含水最多。求这个值。

    其实这个式子也很好糊,考虑一下一个贪心思路,就是尽可能使所有的杯子里含的水更接近。于是我们先算出来操作结束后的总水量,然后除以杯子的数量,但是要注意,答案不能小于初始最小水量。

    #include<bits/stdc++.h>
    using namespace std;
    long long a[10001];//记得一定要long long 不然会挂
    long long n,s;
    int main()
    {
        cin >> n >> s;
        long long mx = 0;
        long long sum = 0;
        long long mn = 1000000000000;
        for(int i = 1;i <= n;i++)
        {
            scanf("%lld",&a[i]);
            mn = min(a[i],mn); 
            sum += a[i];
        }
        if(sum < s) 
        {
            puts("-1");
            return 0;
        }
        cout << min(mn,(sum-s)/n); 
        return 0;
    }

    T3:The Fair Nut and String

    一道典型的结论+字符串题,题目还是比较新颖的。

    题意:

    有一字符串(s.length <= 105),现在你需要求出所有满足条件的location(地址)的子序列。

    它需要满足以下条件:
      1、所有location对应字符都是‘a’;
      2、所有location之间都至少有一个location对应‘b’;

    考虑当你遇到一个b的时候,那么所有在这个b之前就可以满足的子序列都可以加上这个b后面所有出现的a中的一个匹配。

    #include<bits/stdc++.h>
    using namespace std;
    const int mod = 1e9+7;
    char s[100001];
    int main()
    {
        scanf("%s",s+1);
        int len = strlen(s+1);
        long long ans = 1,cnt = 1;
        for(int i = 1;i <= len;i++)
        {
            if(s[i] == 'a') 
                cnt++;
            else if(s[i] == 'b')
            {
                ans = (ans*cnt)%mod;
                cnt = 1;
            }
        }
        ans = (ans*cnt) % mod;
        cout << ans-1 << endl;
        return 0;
    
    }

     T4:The Fair Nut and the Best Path

    一道简单的树型DP题,只要想到了应该还是挺好写的。

    题意:

    有一棵有n (n <=  3*105)个点的树,其中所有的边都是负权的,点是正权的。要求一个权值最大的简单路径。

    考虑树上任意一条简单路径必定是从一个点一直向子树延伸下去。假设任意一个点为始祖的路径,使简单路劲权值最大,那么一定是有最大和次大的两条子链和当前祖先形成的。这个子链大小可以用最大的子链DP直接转移,但是注意如果子链为负,那么不转移,直接使用该点的权值。

    #include<bits/stdc++.h>
    using namespace std;
    int val[300005];
    long long f[300005],dp[300005];
    vector <pair <int, int> > vec[300005];
    int n;
    long long ans = 0;
    void dfs(int u,int fa)
    {
        f[u] = val[u];
        dp[u] = val[u];
        long long mx = 0,Mx = 0;
        for(int i = 0;i < vec[u].size();i++)
        {
            if(vec[u][i].first == fa) continue;
            dfs(vec[u][i].first,u);
            if(mx < f[vec[u][i].first] - vec[u][i].second)
            {
                Mx = mx;
                mx = f[vec[u][i].first] - vec[u][i].second;
            }
            else if(Mx < f[vec[u][i].first] - vec[u][i].second)
            {
                Mx = f[vec[u][i].first] - vec[u][i].second;
            }
        }
        dp[u] += mx;
        dp[u] += Mx;
        f[u] += mx;
        ans = max(max(ans,dp[u]),f[u]);
    }
    int main()
    {
        cin >> n;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&val[i]);
        }
        int u,v,w;
        for(int i = 1;i < n;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            vec[u].push_back(make_pair(v,w));
            vec[v].push_back(make_pair(u,w));
        }
        dfs(1,-1);
        cout << ans << endl;
        return 0;
    }

    T5:The Fair Nut and Strings

    这题好多同机房(当然是最差的机房,我这么菜)的人都卡在这。但是我好想没什么压力就糊出了结论水过了。

    有两个长度为n(n <= 5*105)的“ab”字符串,其中的k个最多有多少前缀和。

    这题其实仔细思考一下只要二进制按位相减就好了。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long n,k;
        cin >> n >> k;
        string s,t;
        cin >> s >> t;
        long long ans = 0;
        long long suma = 0,sumb = 0;
        for(int i = 0;i < n;i++)
        {
            long long now;
            suma *= 2;
            sumb *= 2;
            if(s[i] == 'b') 
                suma++;
            if(t[i] == 'b') 
                sumb++;
            now = sumb - suma + 1;
            if(now >= k)
            {
                ans += (n-i)*k;
                break ;
            }
            ans+=now;
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    使用typescript开发vue项目
    .sync和v-model的区别
    echarts通过dataZoom来控制默认显示固定条数数据
    ES6学习
    angular父子组件相互传值
    premiere中时间轴倍速预览及常用快捷键
    群晖Docker套件下搭建运行MSSQL
    微信的视频下载方法
    Unable to cast object of type 'System.Int32' to type 'System.String'.
    vs2017 2019莫名自动退出调试状态可以尝试一下如下的方法
  • 原文地址:https://www.cnblogs.com/mzyy1001/p/10145496.html
Copyright © 2020-2023  润新知