CCF 201912-03(化学方程式)-待完善

题目信息:参考链接

吐槽:机试要求使用C,本想着找题练练手,结果代码越写越长。。。。。。

使用测试平台,网上找到的测试数据都可以通过,只有60分,实在找不出毛病出在哪儿,哭( ▼-▼ )

  • 输入
  1. H2+O2=H2O
  2. 2H2+O2=2H2O
  3. H2+Cl2=2NaCl
  4. H2+Cl2=2HCl
  5. CH4+2O2=CO2+2H2O
  6. CaCl2+2AgNO3=Ca(NO3)2+2AgCl
  7. 3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
  8. 3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
  9. 4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
  10. 4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
  11. Cu+As=Cs+Au
  12. HCl=ClH
  13. H2O=H2+O2
  14. 2H2+O2=2H2O
  15. HCl()=ClH()
  16. Ca(OH)2A3=CaA3O2H2
  17. 2Ca(OH)2A3=2CaA3O2H2
  18. Ca(OH(CH)2)2A3=CaA3O2H6C4
  19. Ca(OH(CH)2)2A3=CaA3O2H6C5
  20. 2Ca(OH)2A3=CaA3O2H2
  21. NaHCO3=Na2CO3+H2O+CO2
  22. 2NaHCO3=Na2CO3+H2O+CO2
  23. CuCl2=Cu+Cl2
  24. Cu+4HNO3=Cu(NO3)2+2NO2+2H2O
  25. 3Cu+8HNO3=3Cu(NO3)2+2NO+4H2O
  26. Mg+CO2=2MgO+C
  27. 2Mg+CO2=2MgO+C
  28. CuCl2=Cu+Cl2
  29. CuSO4+2NaOH=Cu(OH)2+Na2SO4
  30. 8A(7B(6C(5D(4E(3F(2E2G3)2)3)4)5)2)3=8A(7B(6C(5D(4E(3F(E4G6)2)3)4)5)2)3
  • 输出
  1. N
  2. Y
  3. N
  4. Y
  5. Y
  6. Y
  7. Y
  8. Y
  9. Y
  10. Y
  11. N
  12. Y
  13. N
  14. Y
  15. Y
  16. Y
  17. Y
  18. Y
  19. N
  20. N
  21. N
  22. Y
  23. Y
  24. Y
  25. Y
  26. N
  27. Y
  28. Y
  29. Y
  30. Y
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct{
    int x;
    int y;
}point, *pot;

void H2O();
pot clearStr(char *str, int i);
int isLive(char *one, char **ones, int cnt);
int findWord(char *str, char **ones, int *i, int *num, int *cnt, int flag, int ql);

void H2O(){
    int n, i, tmp, cnt, flag;//cnt 元素个数
    char *str = (char *)malloc(1005);//方程式
    char **ones = (char **)malloc(1005 * sizeof(char*));//化学元素
    int *num = (int *)malloc(1005 * sizeof(int));//元素个数
    scanf("%d", &n);
    while(n > 0){
        scanf("%s", str);
        memset(ones, 0, 1005 * sizeof(char *));
        memset(num, 0, 1005 * sizeof(int));
        i = 0;
        cnt = 0;
        tmp = 0;
        flag = 0;
        while(str[i] != '='){
            if(str[i] == '+'){
                i++;
            }
            findWord(str, ones, &i, num, &cnt, flag, 0);//包含 i++
        }
        i++; flag = 1;
        while(str[i] != '\0'){
            if(str[i] == '+'){
                i++;
            }
            tmp = findWord(str, ones, &i, num, &cnt, flag, 0);
            //tmp = delWord(str, ones, &i, num, cnt);
            if(tmp == -1){
                printf("N\n");
                goto lab;
            }
        }

        //num[] 都为0
        for(tmp = 0; tmp < cnt; tmp++){
            if(num[tmp] != 0){
                break;
            }
        }
        if(tmp == cnt){
            printf("Y\n");
        }
        else{
            printf("N\n");
        }
        lab:
            n--;
    }
}
//找化学式 4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH 3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
int findWord(char *str, char **ones, int *i, int *num, int *cnt, int flag, int ql){
    int x, sit, tmp, stri, strtmp, j;
    char *one, a[10] = {0};
    pot p;

    if(str[*i] >= '1' && str[*i] <= '9' || ql != 0){
        strtmp = 0;
        memset(a, 0, 10);
        while(str[*i] >= '0' && str[*i] <= '9'){
            a[strtmp] = str[*i];
            strtmp++;
            (*i)++;
        }
        a[strtmp] = '\0';
        stri = atoi(a);
        if(ql != 0){
            if(stri != 0)
                x = ql * stri;
            else
                x = ql;
        }
        else{
            x = stri;
            //(*i)++;//!!!!!!!!!!!
        }
    }
    else{
        x = 1;
    }
    while(str[*i] != '\0' && str[*i] != '+' && str[*i] != '=' && str[*i] != ')'){
        //括号处理 Na(Au(CN)2)3
        //pot clearStr(char *str, int i);匹配左右括号
        if(str[*i] == '('){
            p = clearStr(str, *i);
            tmp = p[0].y; //tmp指向左括号对应的右括号
            tmp++;
            (*i)++;
            if(str[tmp] >= '1' && str[tmp] <= '9'){
                strtmp = 0;
                memset(a, 0, 10);
                while(str[tmp] >= '0' && str[tmp] <= '9'){
                    a[strtmp] = str[tmp];
                    strtmp++;
                    tmp++;
                }
                a[strtmp] = '\0';
                stri = atoi(a);
                findWord(str, ones, i, num, cnt, flag, stri * x);
            }
            else
                findWord(str, ones, i, num, cnt, flag, x);
            *i = tmp;
        }
        //findOne(cnt, x, num);找元素
        if(str[*i] >= 'A' && str[*i] <= 'Z' && str[*i + 1] >= 'a' && str[*i + 1] <= 'z'){
            one = (char *)malloc(3);
            one[0] = str[*i];
            one[1] = str[*i + 1];
            one[2] = '\0';
            (*i)++;(*i)++;
            sit = isLive(one, ones, *cnt);
            if(sit == -1){
                if(flag == 0){
                    ones[*cnt] = one;
                    sit = *cnt;
                    (*cnt)++;
                }
                else{
                    return -1;
                }
            }

            if(str[*i] >= '1' && str[*i] <= '9'){
                strtmp = 0;
                memset(a, 0, 10);
                while(str[*i] >= '0' && str[*i] <= '9'){
                    a[strtmp] = str[*i];
                    strtmp++;
                    (*i)++;
                }
                a[strtmp] = '\0';
                stri = atoi(a);
                if(flag == 0){
                    num[sit] +=  x * stri;
                }
                else{
                    num[sit] -=  x * stri;
                }
                //(*i)++;
            }
            else{
                if(flag == 0){
                    num[sit] +=  x;
                }
                else{
                    num[sit] -=  x;
                }
            }
        }
        else if(str[*i] >= 'A' && str[*i] <= 'Z'){
            one = (char *)malloc(2);
            one[0] = str[*i];
            one[1] = '\0';
            (*i)++;
            sit = isLive(one, ones, *cnt);
            if(sit == -1){
                if(flag == 0){
                    ones[*cnt] = one;
                    sit = *cnt;
                    (*cnt)++;
                }
                else{
                    return -1;
                }
            }

            if(str[*i] >= '1' && str[*i] <= '9'){
                strtmp = 0;
                memset(a, 0, 10);
                while(str[*i] >= '0' && str[*i] <= '9'){
                    a[strtmp] = str[*i];
                    strtmp++;
                    (*i)++;
                }
                a[strtmp] = '\0';
                stri = atoi(a);

                if(flag == 0){
                    num[sit] +=  x * stri;
                }
                else{
                    num[sit] -=  x * stri;
                }
                //(*i)++;
            }
            else{
                if(flag == 0){
                    num[sit] +=  x;
                }
                else{
                    num[sit] -=  x;
                }
            }
        }
    }
    return 0;
}

int isLive(char *one, char **ones, int cnt){
    int i;
    for(i = 0; i < cnt; i++){
        if(strcmp(one, ones[i]) == 0){
            return i;
        }
    }
    return -1;
}

//4Na(Au(CN)2)
pot clearStr(char *str, int i){
    int tmp = 0;
    pot a = (pot)malloc(500 * sizeof(point)); //遍历化学式中所有括号
    while(str[i] != '\0' && str[i] != '+' && str[i] != '='){
        if(str[i] == '('){
            a[tmp].x = i;
            tmp++;
        }
        else if(str[i] == ')'){
            tmp--;
            a[tmp].y = i;
        }
        i++;
    }
    return a;
}
int main(){
    H2O();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值