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;
}
posted @ 2020-06-26 11:31  无名菜鸟1  阅读(159)  评论(0编辑  收藏  举报