【无标题】

CCF 2019-12-3 化学方程式(100分, 15ms)

把等号左右运算结果分别存入两个map, 比较map是否一样

括号求解是用DFS做的。

#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef long long ll;
#define MAXN 1005
#define InA(a) a>='A'&&a<='Z'
#define Ina(a) a>='a'&&a<='z'
#define In0(a) a>='0'&&a<='9'

map<string, int> mp[2];
string s;
int quan, mpid;

int to_num(int l, int r){
	int ans=0;
	for(;l<r;l++){
		ans=(ans*10 + s[l]-'0');
	}
	return ans;
}

int getNum(int start){
	while(In0(s[start]))
		start++;
	return start;
}

void dealP(int &ptr){
	quan=1;
	ptr++;
	if( In0(s[ptr] ) ) {//find num after "+"
		int r = getNum(ptr);
		quan = to_num(ptr, r);
		ptr = r;
	}
}

void dealA(int &ptr){
	string ss;
	ss+=s[ptr];
	ptr++;
	
	int num=1;
	if(Ina(s[ptr])){// if followed by a
		ss+=s[ptr];
		ptr++;
	}
	
	if(In0(s[ptr])){// if followed by num
		int r = getNum(ptr);
		num = to_num(ptr, r);
		ptr = r;	
	}
	
	mp[mpid][ss]+=(num*quan);
}

int findrk(int l){// find brackets ')'
	int tt=1;
	while(tt){
		l++;
		if(s[l]=='(')	tt++;
		if(s[l]==')')	tt--;
	}
	return l;
}

void DFS(int &l, int r, int val){//[l,r]
	l++;
	quan*=val;
	while(l<r){
		char c = s[l];
		if(InA(c)) dealA(l);
		else if(c=='('){
			int rr = findrk(l);
			int vall = 1;
			if(In0(s[rr+1])) vall = to_num(rr+1, getNum(rr+1));
			DFS(l, rr, vall);
			l = getNum(rr+1);
		}
	}
	quan/=val;
}

void dealK(int&ptr){
	int ri=1;
	ri = findrk(ptr);
	int valu = 1;
	if(In0(s[ri+1])) {	
		valu = to_num(ri+1, getNum(ri+1));
	}
	DFS(ptr, ri, valu);
	ptr++;
	ptr = getNum(ptr);
}

int main(){
	ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	int i,j,k,n,l=0,r=0,ptr;
	cin>>n;
	
	while(n--){
		cin>>s;
		ptr=0;//set ptr
		s.insert(0,"+");
		int lend = s.find('=');
		s.insert(lend+1,"+");
		
		mpid=0;	//set map
		mp[0].clear(); mp[1].clear();
		int len = s.size();
		
		while(ptr<len){//main loop for one expression
			char c = s[ptr];
			if(c == '+') dealP(ptr);//+
			else if(InA(c)) dealA(ptr);//A
			else if(c == '='){//=
				mpid = 1;//change map id
				ptr++;
			}else{//(
				dealK(ptr);
			}
		}
		
		if(mp[0] == mp[1])
			cout<<"Y"<<endl;
		else
			cout<<"N"<<endl;
	}
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值