1 条题解

  • 0
    @ 2025-8-24 23:17:43

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar xiaowenxu_qwq
    最后在线时间:2025年8月24日21时19分 ,水题主页https://www.luogu.com.cn/training/774850

    搬运于2025-08-24 23:17:43,当前版本为作者最后更新于2025-07-09 18:36:38,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    解题思路

    我们将每个括号设为一层,括号外面的括号比括号里面的括号低一层(碰到左括号时层数加一,碰到右括号时层数减一),用一个数组来计算括号的每一层。最里面的括号设为 1,并列的括号数字相加,每降一层将括号内的数字乘 2。

    部分正确代码。

    #include<bits/stdc++.h>
    using namespace std;
    stack<char>s;
    char c[10000001];
    int cnt[10000001];//定义括号层
    int ans[10];
    int main()
    {
        int t;
        cin>>t;
    	string c;
        while(t--){
            for(int k=1;k<=2;k++){
                cnt[1]=0;
            	cin>>c;
                int len=c.length();
                for(int i=0,j=1;i<len;i++){
            		if(c[i]=='('){
            			s.push(c[i]);
                        j++;
                        cnt[j]=0;
                    }
            		else if(c[i]==')'){
            			if(!s.empty())
            				s.pop();
                        if(c[i-1]=='(')
                            cnt[j-1]++;
                        else
                            cnt[j-1]+=cnt[j]*2;
                        j--;
              		}
                }
                ans[k]=cnt[1];
        	}
            if(ans[1]>ans[2])
                printf(">\n");
            else if(ans[1]<ans[2])
                printf("<\n");
            else if(ans[1]==ans[2])
                printf("=\n");
        }
    	return 0;
    } 
    

    我们会发现,如果所有的括号扩在一起的话,计算出的数字会达到 21.5×1062^{1.5 \times 10^6} 所以代码因用高精度计算。

    高精代码(空间复杂度高)。

    #include <iostream>
    #include <stack>
    #include <cstring>
    using namespace std;
    
    struct BigInt {
        int d[1001];
        int len;
        
        BigInt() : len(0) {
            memset(d, 0, sizeof(d));
        }
        
        explicit BigInt(const string& s) : len(s.length()) {
            memset(d, 0, sizeof(d));
            for(int i = 0; i < len; i++) {
                d[i] = s[len - i - 1] - '0';
            }
        }
        
        void add(const BigInt& other) {
            int carry = 0;
            int max_len = max(len, other.len);
            for(int i = 0; i < max_len; i++) {
                int temp = d[i] + other.d[i] + carry;
                d[i] = temp % 10;
                carry = temp / 10;
            }
            if(carry) d[max_len] = carry;
            len = carry ? max_len + 1 : max_len;
        }
        
        void multiplyByTwo() {
            int carry = 0;
            for(int i = 0; i < len; i++) {
                int temp = d[i] * 2 + carry;
                d[i] = temp % 10;
                carry = temp / 10;
            }
            if(carry) d[len++] = carry;
        }
        
        int compare(const BigInt& other) const {
            if(len != other.len) return len > other.len ? 1 : -1;
            for(int i = len-1; i >= 0; i--) {
                if(d[i] != other.d[i]) return d[i] > other.d[i] ? 1 : -1;
            }
            return 0;
        }
    };
    
    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        
        short t;
        cin >> t;
        string c;
        const BigInt one("1");
        
        while(t--) {
            BigInt ans[2];
            for(int k = 0; k < 2; k++) {
                cin >> c;
                stack<BigInt> st;
                st.push(BigInt());
                
                for(int i = 0; i < c.length(); i++) {
                    if(c[i] == '(') {
                        st.push(BigInt());
                    }
                    else if(c[i] == ')') {
                        BigInt top = st.top();
                        st.pop();
                        if(c[i-1] == '(') {
                            st.top().add(one);
                        } else {
                            top.multiplyByTwo();
                            st.top().add(top);
                        }
                    }
                }
                ans[k] = st.top();
            }
            
            int cmp = ans[0].compare(ans[1]);
            if(cmp > 0) cout << ">\n";
            else if(cmp < 0) cout << "<\n";
            else cout << "=\n";
        }
        
        return 0;
    }
    

    这种暴力的高精度算法空间复杂度较高,所以我们可以对整体进行优化,但还是一层一层的来计算。

    最终代码(全对)。

    #include <bits/stdc++.h>
    using namespace std;
    signed main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int T;
        cin>>T;
        while(T--){
            string A,B;
            cin>>A>>B;
            vector<int>cntA(1500001,0);
            vector<int>cntB(1500001,0);
            int max_dA=0,max_dB=0;
            int d=0;//定义层
            for(int i=0;i<A.size();i++){
                if(A[i]=='('){
                    d++;//层上升
                    if (d>max_dA)
                      max_dA=d;
                }
                else{
                    if(i>0&&A[i-1]=='(')
                        if(d>=1&&d<=1500000)
                            cntA[d]++;//为最里面的括号,将本层的值加一(或设为一)
                    d--;//层下降
                }
            }
            d=0;
            for(int i=0;i<B.size();i++){
                if(B[i]=='('){
                    d++;
                    if(d>max_dB)
                      max_dB = d;
                }
                else{
                    if(i>0&&B[i-1]=='(')
                        if(d>=1&&d<=1500000)
                            cntB[d]++;
                    d--;
                }
            }//重复处理字符串B
            int lenA=max_dA+23;
            int lenB=max_dB+23;
            vector<int>bitsA(lenA,0);
            vector<int>bitsB(lenB,0);
            for (int d_val=1;d_val<=1500000;d_val++){
                if(cntA[d_val]>0)
                    if(d_val-1<lenA)
                        bitsA[d_val-1]+=cntA[d_val];//计算二进制表示
                if (cntB[d_val]>0)
                    if (d_val-1<lenB)
                        bitsB[d_val-1]+=cntB[d_val];//重复处理字符串B
            }
            for(int i=0;i<lenA-1;i++){
                if(bitsA[i]>=2){
                    bitsA[i+1]+=bitsA[i]>>1;
                    bitsA[i]=bitsA[i]&1;//计算二进制表示
                }
            }
            for(int i=0;i<lenB-1;i++){
                if(bitsB[i]>=2){
                    bitsB[i+1]+=bitsB[i]>>1;
                    bitsB[i]=bitsB[i]&1;
                }
            }//重复处理字符串B
            char result='=';
            for (int i=max(lenA,lenB)-1;i>=0;i--) {
                int a_bit=(i<lenA)?bitsA[i]:0;
                int b_bit=(i<lenB)?bitsB[i]:0;
                if(a_bit!=b_bit){
                    result=(a_bit>b_bit)?'>':'<';
                    break;
                }
            }
            cout<<result;
            printf("\n");
        }
        return 0;
    }
    
    • 1

    信息

    ID
    12457
    时间
    6000ms
    内存
    1024MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者