CCF-CSP题解 201912-3 化学方程式

判断化学方程式是否配平。

字符串处理。

有点编译原理递归下降法的感觉。

考场源码,比较粗糙。

// INFO BEGIN
//
// User = 201911513451(陶杨)
// Group = C/C++
// Problem = 化学方程式
// Language = CPP11
// SubmitTime = 2019-12-15 16:20:32
//
// INFO END

#include <cstdio>
#include <cstring>

using namespace std;

char str[1005];

int nums[27][27];

void elementSingle(int l, int r, int left, int coef, int coef2) {
    if (l > r) return;
    int e1, e2 = 0;
    e1 = str[l] - 'A' + 1;  // [1,26]
    if (l < r && !(str[l + 1] >= '0' && str[l + 1] <= '9')) e2 = str[l + 1] - 'a' + 1;
    int mid = l + 1;
    if (e2 != 0) ++mid;
    int co = 0;
    while (mid <= r) co = co * 10 + str[mid++] - '0';
    if (co == 0) co = 1;
    nums[e1][e2] += left * coef * coef2 * co;
}

void element(int l, int r, int left, int coef, int coef2) {
    if (l > r) return;
    // printf("%d %d %d ", left, coef, coef2);
    // for (int i = l; i <= r; ++i) printf("%c", str[i]); printf("\n");
    int mid = l + 1;
    for (; mid <= r && !(str[mid] >= 'A' && str[mid] <= 'Z'); ++mid);
    if (mid <= r) {
        elementSingle(l, mid - 1, left, coef, coef2);
        element(mid, r, left, coef, coef2);
    } else elementSingle(l, r, left, coef, coef2);
}

void formula(int l, int r, int left, int coef, int coef2) {
    if (l > r) return;
    int lb = -1, rb = -1, lmore = 0;
    for (int i = l; i <= r; ++i) {
        if (str[i] == '(') {
            ++lmore;
            if (lb == -1) lb = i;
        }
        if (str[i] == ')') {
            --lmore;
            if (lmore == 0 && rb == -1) rb = i;
        }
        if (rb != -1) break;
    }
    if (rb == -1) element(l, r, left, coef, coef2); else {
        int co = 0, mid = rb + 1;
        for (; mid <= r && str[mid] >= '0' && str[mid] <= '9'; ++mid) co = co * 10 + str[mid] - '0';
        if (co == 0) co = 1;
        element(l, lb - 1, left, coef, coef2);
        formula(lb + 1, rb - 1, left, coef, coef2 * co);
        formula(mid, r, left, coef, coef2);
    }
}

void exprSingle(int l, int r, int left) {
    if (l > r) return;
    int coef = 0, mid = l;
    for (; mid <= r && str[mid] >= '0' && str[mid] <= '9'; ++mid) coef = coef * 10 + str[mid] - '0';
    if (coef == 0) coef = 1;
    formula(mid, r, left, coef, 1);
}

void expr(int l, int r, int left) {
    if (l > r) return;
    int mid = l;
    for (; mid <= r && str[mid] != '+'; ++mid);
    if (mid <= r) {
        exprSingle(l, mid - 1, left);
        expr(mid + 1, r, left);
    } else exprSingle(l, r, left);
}

// [l,r]
void equation(int l, int r) {
    if (l > r) return;
    int mid = l;
    for (; str[mid] != '='; ++mid);
    expr(l, mid - 1, 1);
    expr(mid + 1, r, -1);
}

int main() {
    int n;
    scanf("%d", &n);
    for (int _ = 0; _ < n; ++_) {
        scanf("%s", str);
        memset(nums, 0, sizeof(nums));
        equation(0, strlen(str) - 1);
        bool flag = true;
        for (int i = 1; i <= 26; ++i) {
            for (int j = 0; j <= 26; ++j) {
                if (nums[i][j] != 0)
                    flag = false;
            }
        }
        if (flag) printf("Y\n");
        else printf("N\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/acboyty/p/12074604.html

时间: 2024-10-22 18:39:42

CCF-CSP题解 201912-3 化学方程式的相关文章

ccf csp题解201312-1

试题编号: 201312-1 试题名称: 出现次数最多的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个正整数,找出它们中出现次数最多的数.如果这样的数有多个,请输出其中最小的一个. 输入格式 输入的第一行只有一个正整数n(1 ≤ n ≤ 1000),表示数字的个数. 输入的第二行有n个整数s1, s2, -, sn (1 ≤ si ≤ 10000, 1 ≤ i ≤ n).相邻的数用空格分隔. 输出格式 输出这n个次数中出现次数最多的数.如果这样的数有多个,输

CCF CSP 201712-2 游戏

题目链接:http://118.190.20.162/view.page?gpid=T67 问题描述 有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向. 游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1.若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数.当游戏中只剩下一个小朋友时,该小朋友获胜.

记第十七次CCF CSP认证

记第十七次CCF CSP认证 第一二题很简单,就是简单的模拟就可以了,后面的第三四题用了近一个小时才看懂,但是感觉好复杂,不好写,能力不行,写不出来.第五题,就想到了暴力,其他就不会了,但是我没有去写,因为感觉这个复杂度就算写了也过不了.最后检查了几遍第一二题的代码,范围我开的都比题目要求的大一个数量级.最后就过了这两个题. 下次12月份继续! 原文地址:https://www.cnblogs.com/alking1001/p/11536021.html

CCF CSP个人题解汇总

趁着这波考CCF热来骗一波访问量 祝自己免修算法RP++ 区域赛RP++ 1.2题汇总在这:https://www.cnblogs.com/QAQorz/p/9650890.html 201803-4 棋局评估(对抗搜索):https://www.cnblogs.com/QAQorz/p/9650828.html 201712-4 行车路线(最短路):https://www.cnblogs.com/QAQorz/p/9588268.html 原文地址:https://www.cnblogs.co

2019年12月ccf csp认证第三题-判断是否配平化学方程式

#include<bits/stdc++.h> using namespace std; int n; string s; void solve_son(queue<string>&q,int bei,map<string,int>&m) { while(!q.empty()) { string ts = q.front(); q.pop(); if(ts=="(") { int left = 1,right = 0; queue&l

CCF CSP历年一二题代码汇总

实话说如果不是为了骗访问量,才不会写12题的qwq 201803-1 跳一跳 第一题向来是送分题...但是注意读题... 模拟题按题意走是坠稳的 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define LL long long 6 #define debug(x) cout << "[" <&l

第16次CCF CSP认证-第5题-317 号子任务(subtask317)-图论最短路径

[题目背景]“你在平原上走着走着,突然迎面遇到一堵墙,这墙向上无限高,向下无限深,向左无限远,向右无限远,这墙是什么?”——<流浪地球>原著我们带着地球去流浪了,为了处理流浪过程中可能会发生的危机,联合政府找到你,希望你能协助完成 317 号子任务:制定应急预案.[题目描述]地球的表面有 n 个据点,这些据点之间存在 m 条双向道路.这些据点中,有的是建立在行星发动机之下,受到行星发动机的保护(行星发动机据点),而其他据点则没有行星发动机的保护(普通据点,比如燃料采集据点/科研据点等).当发生

CCF CSP 201803-1 跳一跳

题目链接:http://118.190.20.162/view.page?gpid=T73 问题描述 近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱. 简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束. 如果跳到了方块上,但没有跳到方块的中心则获得1分:跳到方块中心时,若上一次的得分为1分或这是本局游戏的第一次跳跃则此次得分为2分,否则此次得分比上一次得分多两分(即连续跳到方块中心时,总得分将+2,+4,+6,+8...). 现在给出一个人跳一跳的

【算法题】CCF CSP 1403-1

试题编号: 201403-1试题名称: 相反数时间限制: 1.0s内存限制: 256.0MB 问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数).输入格式 第一行包含一个正整数 N.(1 ≤ N ≤ 500). 第二行为 N 个用单个空格隔开的非零整数,每个数的绝对值不超过1000,保证这些整数各不相同.输出格式 只输出一个整数,即这 N 个数中包含多少对相反数.样例输入51 2 3 -1 -2样例输出2 n = int(input()

【算法题】CCF CSP第三题练习

 样例全部没问题,但是只有40分,不知道哪里出问题了: #include <iostream> #include <string> #include <map> #include <sstream> using namespace std; class Fomular { private: string s, sr, sp; map<string,int> reactant; map<string,int> product; map&