题解 CCF-CSP-18-C 化学方程式 AcWing 3284
本文最后更新于 300 天前,其中的信息可能已经有所发展或是发生改变。

题目传送门

题解

这个题是一道恶心人的大模拟,如何处理检查配平情况呢?要找出所有的原子,计数,然后比对等号两边各种原子的数量。

处理原子可以用 unordered_map,但是效率不高切更难写,我们可以开一个 $27*27$ 的数组,把原子转换为数组下标,这样更高效。

关于括号的嵌套,我的想法是开一个 tag 数组,先扫一个化学式,确定括号的位置以及化学计量数,然后更新 tag,正数代表乘,负数代表除。

还有一个容易出现的 bug:数字有可能出现很多位,刚开始我只考虑了一位,所以调了很久。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 27 * 27 + 5;

#define SIZ s.size()

int a[N], b[N];
int tag[1005];

int n;

int ans;

string s;

void div1(string str) {
    // cout << str << endl;

    for (int i = 0; i < str.size();) {
        int j = i + 1;
        while (str[j] != '+' && j < str.size())
            j++;
        string cur = str.substr(i, j - i);
        i = j + 1;
        int times = 1;
        int now = 0;
        memset(tag, 0, sizeof tag);
        if (cur[0] >= '1' && cur[0] <= '9') {
            int number = 0;

            while (cur[now] >= '0' && cur[now] <= '9') {
                number = number * 10 + cur[now] - '0';
                now++;
            }
            times *= number;
            now--;
        }
        while (now < cur.size()) {
            if (cur[now] == '(') {
                int l = 1, k = now + 1;
                while (1) {
                    if (cur[k] == '(')
                        l++;
                    if (cur[k] == ')')
                        l--;
                    if (l == 0) {
                        int tmp = 0;
                        if (cur[k + 1] < '0' || cur[k + 1] > '9')
                            tmp = 1;
                        int p = k + 1;
                        while (cur[p] >= '0' && cur[p] <= '9') {
                            tmp = tmp * 10 + cur[p] - '0';
                            p++;
                        }

                        tag[now] = tmp;
                        tag[k] = tmp * -1;
                        cerr << "add tag on " << now << " value = " << tmp
                             << endl;
                        break;
                    }
                    k++;
                }
            }
            now++;
        }

        now = 0;
        while (1) {
            if (now >= cur.size())
                break;

            if (tag[now] > 0)
                times *= tag[now];
            if (tag[now] < 0)
                times /= tag[now] * -1;
            if (!((cur[now] >= 'a' && cur[now] <= 'z') ||
                  (cur[now] >= 'A' && cur[now] <= 'Z'))) {
                now++;
                continue;
            }
            int tim = 1;
            if ((cur[now + 1] >= 'A' && cur[now + 1] <= 'Z') ||
                cur[now + 1] == '(' || cur[now + 1] == ')' ||
                now + 1 >= cur.size()) {
                a[(cur[now] - 'A' + 1) * 10] += 1 * times;
                cerr << "find " << cur[now] << " 我们给他加上了 " << 1 * times
                     << endl;
            }
            if ((cur[now + 1] >= '0' && cur[now + 1] <= '9')) {
                int number = 0;
                int p = now + 1;
                while (cur[p] >= '0' && cur[p] <= '9') {
                    number = number * 10 + cur[p] - '0';
                    p++;
                }

                a[(cur[now] - 'A' + 1) * 10] += (number)*times;

                cerr << "find " << cur[now] << number << " 我们给他加上了 "
                     << (number)*times << endl;
                now = p - 1;
            }
            if ((cur[now + 1] >= 'a' && cur[now + 1] <= 'z')) {
                if ((cur[now + 2] >= '0' && cur[now + 2] <= '9')) {

                    int number = 0;
                    int p = now + 2;
                    while (cur[p] >= '0' && cur[p] <= '9') {
                        number = number * 10 + cur[p] - '0';
                        p++;
                    }

                    cerr << "find Aa0" << cur[now] << cur[now + 1]
                         << cur[now + 2] << " 我们给他加上了 " << (number)*times
                         << endl;

                    a[(cur[now] - 'A' + 1) * 10 + cur[now + 1] - 'a' + 1] +=
                        (number)*times;
                    now = p - 1;

                } else {

                    cerr << "find Aa" << cur[now] << cur[now + 1]
                         << " 我们给他加上了 " << 1 * times << endl;

                    a[(cur[now] - 'A' + 1) * 10 + cur[now + 1] - 'a' + 1] +=
                        (1) * times,
                        now++;
                }
            }
            now++;
        }
        // for (int i = 0; i <= 20; i++)
        //     cout << tag[i] << " ";
        // cout << endl;
        // int qaq = 0;
    }
}

void div2(string str) {
    // cout << str << endl;

    for (int i = 0; i < str.size();) {
        int j = i + 1;
        while (str[j] != '+' && j < str.size())
            j++;
        string cur = str.substr(i, j - i);
        i = j + 1;
        int times = 1;
        int now = 0;
        memset(tag, 0, sizeof tag);
        if (cur[0] >= '1' && cur[0] <= '9') {
            int number = 0;

            while (cur[now] >= '0' && cur[now] <= '9') {
                number = number * 10 + cur[now] - '0';
                now++;
            }
            times *= number;
            now--;
        }
        while (now < cur.size()) {
            if (cur[now] == '(') {
                int l = 1, k = now + 1;
                while (1) {
                    if (cur[k] == '(')
                        l++;
                    if (cur[k] == ')')
                        l--;
                    if (l == 0) {
                        int tmp = 0;
                        if (cur[k + 1] < '0' || cur[k + 1] > '9')
                            tmp = 1;
                        int p = k + 1;
                        while (cur[p] >= '0' && cur[p] <= '9') {
                            tmp = tmp * 10 + cur[p] - '0';
                            p++;
                        }
                        tag[now] = tmp;
                        tag[k] = tmp * -1;
                        cerr << "add tag on " << now << " value = " << tmp
                             << endl;
                        break;
                    }
                    k++;
                }
            }
            now++;
        }

        now = 0;
        while (1) {
            if (now >= cur.size())
                break;

            if (tag[now] > 0)
                times *= tag[now];
            if (tag[now] < 0)
                times /= tag[now] * -1;
            if (!((cur[now] >= 'a' && cur[now] <= 'z') ||
                  (cur[now] >= 'A' && cur[now] <= 'Z'))) {
                now++;
                continue;
            }
            int tim = 1;
            if ((cur[now + 1] >= 'A' && cur[now + 1] <= 'Z') ||
                cur[now + 1] == '(' || cur[now + 1] == ')' ||
                now + 1 >= cur.size()) {
                b[(cur[now] - 'A' + 1) * 10] += 1 * times;
                cerr << "find " << cur[now] << " 我们给他加上了 " << 1 * times
                     << endl;
            }
            if ((cur[now + 1] >= '0' && cur[now + 1] <= '9')) {
                int number = 0;
                int p = now + 1;
                while (cur[p] >= '0' && cur[p] <= '9') {
                    number = number * 10 + cur[p] - '0';
                    p++;
                }

                b[(cur[now] - 'A' + 1) * 10] += (number)*times;

                cerr << "find " << cur[now] << number << " 我们给他加上了 "
                     << (number)*times << endl;
                now = p - 1;
            }
            if ((cur[now + 1] >= 'a' && cur[now + 1] <= 'z')) {
                if ((cur[now + 2] >= '0' && cur[now + 2] <= '9')) {

                    int number = 0;
                    int p = now + 2;
                    while (cur[p] >= '0' && cur[p] <= '9') {
                        number = number * 10 + cur[p] - '0';
                        p++;
                    }

                    cerr << "find Aa0" << cur[now] << cur[now + 1]
                         << cur[now + 2] << " 我们给他加上了 " << (number)*times
                         << endl;

                    b[(cur[now] - 'A' + 1) * 10 + cur[now + 1] - 'a' + 1] +=
                        (number)*times;
                    now = p - 1;

                } else {

                    cerr << "find Aa" << cur[now] << cur[now + 1]
                         << " 我们给他加上了 " << 1 * times << endl;

                    b[(cur[now] - 'A' + 1) * 10 + cur[now + 1] - 'a' + 1] +=
                        (1) * times,
                        now++;
                }
            }
            now++;
        }
        // for (int i = 0; i <= 20; i++)
        //     cout << tag[i] << " ";
        // cout << endl;
        // int qaq = 0;
    }
}

void pd() {
    for (int i = 0; i < N; i++)
        if (a[i] != b[i]) {
            cout << "N" << endl;
            return;
        }
    cout << "Y" << endl;
    return;
}

int main() {
    scanf("%d", &n);
    while (n--) {
        cin >> s;
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
        ans = 0;
        for (int i = 0; i < SIZ; i++) {
            if (s[i] != '=')
                continue;
            div1(s.substr(0, i));
            div2(s.substr(i + 1));
        }
        pd();
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇