zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 90 (Rated for Div. 2)A、B、C、D

    题目
    A题意:两家商店卖相同产品但售卖方式不同,第一家零售一件一件卖价格为a元,第二家b(b>=2)件一起卖(如果要买得话就得向上取整)c元,问在第一家商店买多少会比第二家便宜,
    在第二家商店买多少会比第一家便宜。答案至少买一件否则输出-1.
    解法:首先考虑第一家商店买:如果a>=c,无论如何买都无法比第二家买便宜,因为c是至少两件商品得价格,a是一件商品价格。如果a<c,那就买一件一定在第二家便宜。
    考虑第二家商店买:如果在第一家店买b件比在第二家贵,那就买b件,否则不可能比第一家便宜。

    void solve(){
        int a , b , c ;
        cin >> a >> b >> c;
        if(a < c){//考虑第一商家
            cout << 1 << " " ;
        }else{
            cout << -1 << " " ;
        }
        if(a*b>c){//考虑第二商家且第一商家贵
            cout << b << endl;
        }else{//第一商家便宜
            cout << -1 << endl;
        }
    }
    

    B题意:给出一个01字符串,操作:选择删除任意两个相邻且不同得字符,alice和bob轮流操作,不能操作一方为输方。问Alice是否赢,能输出'DA',不能'NET'.

    char s[maxn];
     
    void solve(){
        scanf("%s" , s+1);
        int a = 0 , b = 0;
        rep(i , 1 , strlen(s+1)){
            if(s[i] == '0')
                a++;
            else{
                b++;
            }
        }
        int ans = min(a , b);
        if(ans%2==1){
            cout << "DA" << endl;
        }else{
            cout << "NET" << endl;
        }
    }
    

    C题意:给出一段伪代码计算代码中得res值。

    res = 0
    for init = 0 to inf
        cur = init
        ok = true
        for i = 1 to |s|
            res = res + 1
            if s[i] == '+'
                cur = cur + 1
            else
                cur = cur - 1
            if cur < 0
                ok = false
                break
        if ok
            break
    

    解法:前缀记录信息可以不需要外层循环 , 外层循环结束时内层循环一定被完整遍历没有被break,所以最后加上字符串长度。

    const int maxn = 1e6+9;
    char s[maxn];
    void solve(){
        scanf("%s" , s+1);
        int n = strlen(s+1);
        int res = 0 , cur = 0 , ans = 0 , init = 0 ;
        rep(i , 1 , n){
            if(s[i] == '-'){
                cur++;
            }else{
                cur--;
            }
            if(cur > init){
                ans += i ;
                init = cur ;
            }
        }
        cout << ans+n << endl;
    }
    

    D题意:给出一个数组a下标从0开始,可以进行至多一次操作:对其子数组进行一次翻转。问偶数下标得最大和为多少。
    解法:翻转某一偶数长区间该区间翻转贡献最大。如果直接枚举偶数区间(O(n^2))肯定是不行的,可以进行两次dp求最大连续和时间复杂度为O(n)。

    const int maxn = 2e5+9;
    int a[maxn];
    
    void solve(){
        int n ;
        cin >> n;
        int sum = 0;
        rep(i , 0 , n-1){
            cin >> a[i];
            if(i%2==0)
                sum += a[i];
        }
        int i = 1 , ma = 0 , ans = 0;
        while(i+1 < n){//从第二个元素开始
            ans += a[i] - a[i+1];
            ma = max(ma , ans);//取可以贡献最大得区间翻转
            if(ans < 0) ans = 0;//如果前面和是负得就截断
            i+=2;
        }
        i = 0 , ans = 0 ;
        while(i+1 < n){
            ans += a[i+1] - a[i];
            ma = max(ma , ans);
            if(ans < 0) ans = 0;
            i += 2 ;
        }
        cout << sum + ma << endl;
    }
    
  • 相关阅读:
    解析3D打印切片软件:Cura
    步步为营,打造CQUI UI框架
    PHP为什么empty可以访问不存在的索引
    这是一篇关于魔法(Science)上网的教程
    【新阁教育】这样玩PLC,是不是有意思多了
    「新阁教育」西门子TIA实现BadApple完整实例
    C#数据结构-赫夫曼树
    C#数据结构-线索化二叉树
    SQL优化器-RBO与CBO分别是什么
    Linux下安装并配置VSCode(Visual Studio Code)
  • 原文地址:https://www.cnblogs.com/nonames/p/13194240.html
Copyright © 2011-2022 走看看