1 条题解

  • 0
    @ 2025-8-24 22:38:01

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 02Ljh
    qwq

    搬运于2025-08-24 22:38:01,当前版本为作者最后更新于2022-05-05 19:04:09,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    题意

    给我们一个化学式,让我检查该化学式有没有配平。如果配平了,输出 DA,否则输出NE

    配平(学过的可以自动跳过)

    化学反应方程式严格遵守质量守恒定律

    说人话,配平就是化学方程式中等号 ( \to 号)两端每个元素数量都一样

    举个栗子:

    2O2+H2=2H2O2\text{O}_2+\text{H}_2=2\text{H}_2\text{O} 在这个化学式中,左侧有 2 个 O\text{O} (氧元素) 与 2×22\times2H\text{H} (氢元素),而右侧也有 2×22\times2H\text{H} 与 2 个 O\text{O} ,所以该化学式平衡。

    tips

    这题其实非常水。

    根据上面的分析,我们只需要扫一遍该化学式,统计化学式前后的元素数量,开一个结构体,以 \to 作为化学式前后的分隔,分别统计之后再检查就行了。 (具体细节见代码)

    易错点

    话说只有我这种蒟蒻会错

    1. 多测不清空,爆 0 两行泪!!!
    2. 字符转成整数一定要 -'0' !!!
    3. 2H2O2\text{H}_2\text{O} 指的是 2(H2O)2(\text{H}_2\text{O}) 而不是 2H22\text{H}_2O\text{O} !!!

    code

    #include <bits/stdc++.h>
    using namespace std;
    struct node
    {
    	    bool f=false;//这个元素有没有被访问过
    	    int f_num=0;//这元素在化学式前面的数量
            int e_num=0;//这元素在化学式后面的数量
    } ;
    bool deal()
    { 
    	     node xy[1001];
    	     int flag=1;//1表示前半部分 -1表示后半部分
             int tim=-1;//tim表示整个化学式的系数( 2H2O 中的 2 )
             string s;
    	     cin>>s;
    	     int len=s.size();
        	 for(int i=0;i<len;i++)
    	     {
    		    if(s[i]=='-'&&s[i+1]=='>') { flag=-1; tim=-1; i++; continue; }//分隔化学的前半部分和后半部分,更新flag
    	    	if(tim==-1)
    	    	{
    		    	if(isdigit(s[i])) { tim=s[i]-'0'; continue; }//将化学式的系数的值赋给tim。
    		    	else tim=1;//如果该化学式没有系数,那么系数就是1
    		    }
    		    if(s[i]=='+') { tim=-1; continue; }//遇到连接化学式的时候,清零tim
    		    if(isdigit(s[i])&&isalpha(s[i-1])&&i!=0)//处理 H20 中的 H2 (该化学式的原子数)
    	        {
    		    	int w=s[i]-'0';
    		    	w=w*tim;//该元素的原子数乘上系数
    			    xy[(int)(s[i-1])].f=true;//标记为访问过
    			    if(flag==1) xy[(int)(s[i-1])].f_num+=w;//分别处理化学式的前后部分
    			    else xy[(int)(s[i-1])].e_num+=w;
    		    }
    		    if(isalpha(s[i])&&!isdigit(s[i+1]))
    		    {//处理 H2O 中的 O 部分(只有一个元素单质的)
    			    xy[(int)(s[i])].f=true;
    			    if(flag==1) { xy[(int)(s[i])].f_num+=tim; }
    			    else if(flag==-1) { xy[(int)(s[i])].e_num+=tim; } 
    		    }
    	    }
    	    for(int i='A';i<'z';i++)//从'A'到'z'依次查询
    	    {
    		    if(!xy[i].f) continue;//如果没有被使用过,循环继续    
    		    else 
    		    {
    		        if(xy[i].e_num==xy[i].f_num) { continue; }//如果相等就继续
    		    	else return false;//否则直接结束
                }
    	    }
            return true;
    }
    int main()
    {
    	    int n;
    	    cin>>n;
    	    while(n--)
        	{
    	    	if(deal()) puts("DA");
    	    	else puts("NE");
        	}
    	    return 0;//完结撒花 qwq
    }
    //P8234
    

    p.s QAQ 这是本蒟蒻发的第一个题解 都这么晚了我还在写题解 求管理员大大给过

    • 1

    信息

    ID
    7625
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者