Atcoder Beginner Contest 283 C-D

C-Cash Register

题面

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 300points

Problem Statement

Takahashi is a cashier.

There is a cash register with 11 keys: 00012345678, and 9. The cash register initially displays 00. Whenever he types the key 00, the displayed number is multiplied by 100; whenever he types one of the others, the displayed number is multiplied by 10, and then added by the number written on the key.

Takahashi wants the cash register to display an integer SS. At least how many keystrokes are required to make it display S?

Constraints

  • 1 <= s <= 
  • S is an integer. 

题意大概

一个计算器 , 里面有 00, 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9这些键,

然后给你一串数字,问你至少要按多少次键盘按出这个数字。

题解

把这个数存为一个字符串。循环遍历这个字符串,如果遍历到的字符是正数,那么计数器+1。如果是0,如果下一个也是0,那么计数器+1,然后跳过下一个;如果下一个不是0,直接计数器+1,不用跳过。最后输出计数器。

AC Code:

#include<bits/stdc++.h>
using namespace std;
#define M 5005
#define N 500005
#define int long long
#define endl "\n"
template <class T>
int rets(T x) {cout << x << endl; return 0;}
string s;
void init(){
    ios::sync_with_stdio (false);
    cin.tie(0);
    cout.tie(0);
}
signed main(){
    int n,m,k;
    init();
    cin >> s;
    int cnt = 0;
    for (int i = 0 ; i < s.size() ;i ++){
        if (i + 1 != s.size() && s[i] == '0' && s[i + 1] == '0'){
            cnt ++;
            i ++;
            // cout << 1 << endl; 
        }
        else cnt ++;
    }
    cout << cnt <<  endl; 
    return 0;
}

D - Scope

题面

Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400 points

Problem Statement

A string consisting of lowercase English letters, (, and ) is said to be a good string if you can make it an empty string by the following procedure:

  • First, remove all lowercase English letters.
  • Then, repeatedly remove consecutive () while possible.

For example, ((a)ba) is a good string, because removing all lowercase English letters yields (()), from which we can remove consecutive () at the 22-nd and 33-rd characters to obtain (), which in turn ends up in an empty string.

You are given a good string SS. We denote by S_iSi​ the ii-th character of SS.

For each lowercase English letter ab, \ldots…, and z, we have a ball with the letter written on it. Additionally, we have an empty box.

For each i = 1,2,i=1,2, … ,|S|,∣S∣ in this order, Takahashi performs the following operation unless he faints.

  • If Si​ is a lowercase English letter, put the ball with the letter written on it into the box. If the ball is already in the box, he faints.
  • If Si is (, do nothing.
  • If Si​ is ), take the maximum integer j less than i such that the j-th through i-th characters of S form a good string. (We can prove that such an integer j always exists.) Take out from the box all the balls that he has put in the j-th through i-th operations.

Determine if Takahashi can complete the sequence of operations without fainting.

  • 1≤∣S∣≤3e5
  • S is a good string.

题意

有一个由小写字母组成的字符串,如果把他的小写字母去掉且括号成对,那他就是好的。

现在给你一个字符串,如果字符当前为小写字母,就把它放进盒子里。如果为前括号不做操作,

如果为后括号,就找到以他为结尾的好的字符串,把这个好的字符串里的,在盒子里的字符给删掉,全删掉。

如果盒子里出现了同样的字符,那Takahashi就会晕掉,在Takahashi晕掉之前,他能不能把整个字符串的操作全做完。

题解

首先,我们按正常操作来。记录每个后括号的前括号。遍历字符串。当遇到一个字符串,用一个map记录这个字符的计数器,如果这个计数器不为0,那么输出“No”,因为Takahashi会晕掉。

然后将这个计数器+1

如果为后括号,那么跳到前括号那里,遇到一个字母,就将他的计数器-1,然后写出了一份代码。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 1048586
#define M 5005
#define N 500005
#define int long long
#define endl "\n"
#define _clear(q) while (!q.empty()){q.pop();}
template <class T>
int rets(T x) {cout << x << endl; return 0;}
string s;
void init(){
    ios::sync_with_stdio (false);
    cin.tie(0);
    cout.tie(0);
}
deque <int> q;
int f[N];
bool is(char c){return 'a' <= c && c <= 'z';}
map <char ,int> mp;
signed main(){
    int n,m,k;
    init();
    cin >> s;
    for (int i = 0 ; i < s.size() ; i ++){
        if (s[i] == '(') q.push_back(i);
        else if (s[i] == ')'){
            f[i] = q.back();
            q.pop_back();
        }
    }
    for (int i = 0 ; i < s.size() ; i ++){
        if (is(s[i])) {
            if (mp[s[i]]) return rets("No");
            mp[s[i]] ++;
        }
        else if (s[i] == ')'){
            for (int j = f[i]; j <= i ; j ++){
                if (is(s[j])) mp[s[j]] --;
            }
        }
    }
    rets("Yes");
    return 0;
}


恭喜你,WA!

为什么会WA?

因为当一个东西被很多个括号套起来时,会被重复计算。

所以,当我们遇到一个前括号时,要想传送门一样(所以我们需要另外一个数组记录前括号对应的后括号),传送到他的后括号(同时也有优化他的效率)。

 其实,刚开始,本人并没有试过,换句话说,我上来就AC了,为什么?因为我觉得上述代码的效率不高。于是,我把它优化了,没想到误打误撞的AC了。所以以后大家要多用优化好的代码。

暴力代码不一定完全能对。

AC Code:


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 1048586
#define M 5005
#define N 500005
#define int long long
#define endl "\n"
#define _clear(q) while (!q.empty()){q.pop();}
template <class T>
int rets(T x) {cout << x << endl; return 0;}
string s;
void init(){
    ios::sync_with_stdio (false);
    cin.tie(0);
    cout.tie(0);
}
deque <int> q;
int f[N],b[N];
bool is(char c){return 'a' <= c && c <= 'z';}
map <char ,int> mp;
signed main(){
    int n,m,k;
    init();
    cin >> s;
    for (int i = 0 ; i < s.size() ; i ++){
        if (s[i] == '(') q.push_back(i);
        else if (s[i] == ')'){
            f[i] = q.back();
            q.pop_back();
        }
    }
    for (int i = s.size() - 1 ; i >= 0 ; i --){
        if (s[i] == ')') q.push_back(i);
        else if (s[i] == '('){
            b[i] = q.back();
            q.pop_back();
        }
    }
    for (int i = 0 ; i < s.size() ; i ++){
        if (is(s[i])) {
            if (mp[s[i]]) return rets("No");
            mp[s[i]] ++;
        }
        else if (s[i] == ')'){
            for (int j = f[i] + 1 ; j <= i ; j ++) {
                if (s[j] == '(') j = b[j];
                else if (is(s[j])) mp[s[j]] --;
            }
        }
    }
    return rets("Yes");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值