• 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;
    }
    
  • 相关阅读:
    HDU 5486 Difference of Clustering 图论
    HDU 5481 Desiderium 动态规划
    hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值
    HDU 5478 Can you find it 随机化 数学
    HDU 5477 A Sweet Journey 水题
    HDU 5476 Explore Track of Point 数学平几
    HDU 5475 An easy problem 线段树
    ZOJ 3829 Known Notation 贪心
    ZOJ 3827 Information Entropy 水题
    zoj 3823 Excavator Contest 构造
  • 原文地址:https://www.cnblogs.com/nonames/p/13194240.html
Copyright © 2020-2023  润新知