LKNGOAC - Liệt kê cặp dấu ngoặc

Xem dạng PDF

Gửi bài giải


Điểm: 1,00 (OI)
Giới hạn thời gian: 1.0s
Giới hạn bộ nhớ: 256M

Tác giả:
Dạng bài
Ngôn ngữ cho phép
C, C#, C++, Go, Java, Pascal, Perl, PHP, PyPy, Python, Ruby, Rust, Scratch, Swift

Cho dãy ngoặc đúng gồm ~n~ dấu mở ngoặc ( và ~n~ dấu đóng ngoặc ). Các dấu ngoặc được đánh số thứ tự từ ~1~ đến ~2n~. Hãy liệt kê chỉ số của các cặp dấu mở ngoặc và đóng ngoặc tương ứng.

Input

  • Gồm một dòng duy nhất chứa xâu ký tự biểu diễn dãy ngoặc.

Giới hạn:

  • ~1 ≤ n ≤ 10^5~.

Output

  • Gồm ~n~ dòng, mỗi dòng gồm hai số ~u, v~ là chỉ số của các cặp ngoặc tương ứng nhau, thứ tự liệt kê tăng dần theo chỉ số của dấu ngoặc đóng.

Sample

Input #1
()(()())
Output #1
1 2
4 5
6 7
3 8

Problem source: Chuyên Sơn La Online Judge


Bình luận

Please read the guidelines before commenting.



  • -2
    congtyluuthaibao1978  đã bình luận lúc 28, Tháng 11, 2025, 6:46

    include <bits/stdc++.h>

    using namespace std;

    int precedence(char c) { if(c == '+' || c == '-') return 1; if(c == '*' || c == '/') return 2; if(c == '^') return 3; return 0; }

    void RPN() { stack<char> st; string s; cin >> s; // mỗi test case 1 biểu thức không có khoảng trắng string out = "";

    for(char c : s) {
        if(islower(c)) { 
            out += c;
        } 
        else if(c == '(') {
            st.push(c);
        } 
        else if(c == ')') {
            while(!st.empty() && st.top() != '(') {
                out += st.top();
                st.pop();
            }
            if(!st.empty()) st.pop();
        } 
        else if(c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {
            while(!st.empty() && st.top() != '(' &&
                 (precedence(st.top()) > precedence(c) || 
                 (precedence(st.top()) == precedence(c) && c != '^'))) {
                out += st.top();
                st.pop();
            }
            st.push(c);
        }
    }
    
    while(!st.empty()) {
        out += st.top();
        st.pop();
    }
    
    cout << out << "\n";
    

    }

    int main() { ios::syncwithstdio(false); cin.tie(nullptr);

    int t;
    cin >> t;
    while(t--) RPN();
    
    return 0;
    

    }


  • -2
    congtyluuthaibao1978  đã bình luận lúc 28, Tháng 11, 2025, 6:25

    include <bits/stdc++.h>

    using namespace std;

    int main() { ios::syncwithstdio(false); cin.tie(nullptr);

    string s;
    if (!getline(cin, s)) return 0;  // đọc chuỗi ngoặc
    
    int len = s.size();
    stack<int> st;
    vector<pair<int,int>> res; 
    res.reserve(len/2);
    
    for (int i = 0; i < len; i++) {
        if (s[i] == '(') {
            st.push(i + 1);  // dùng 1‑based index
        } else if (s[i] == ')') {
            if (!st.empty()) {
                int open_idx = st.top();
                st.pop();
                res.emplace_back(open_idx, i + 1);
            }
        }
    }
    
    // Vì yêu cầu: in theo thứ tự tăng dần theo chỉ số của dấu đóng
    sort(res.begin(), res.end(), [](const pair<int,int>& a, const pair<int,int>& b) {
        return a.second < b.second;
    });
    
    for (auto &p : res) {
        cout << p.first << " " << p.second << "\n";
    }
    
    return 0;
    

    }


  • 1
    0988440189  đã bình luận lúc 17, Tháng 5, 2025, 16:52

    ý tưởng của mình là các bạn cứ gặp kí tự '(' thì thêm chỉ số thứ tự vào ngăn xếp , ngược lại nếu gặp ')' thì sẽ in ra đầu ngăn xếp và vị trí hiện tại ... Như ví dụ trên : i=0 =>s[i]='(' => stack thêm 1 i=1 =>s[i]=')'=>lấy ra phần tử cuối cùng stack và in vị trí hiện tại ,rồi xóa thằng 1 đi . i=2=>s[i]='(' =>stack thêm 3 i=3=>s[i]='('=>stack thêm 4 i=4 =>s[i]=')'=>ấy ra phần tử cuối cùng stack và in vị trí hiện tại ,rồi xóa thằng 4 đi.(stack vẫn còn thằng 3) ... cứ làm như thế thì sẽ đc các dấu đóng mở ngoặc tương ứng .