「AOJ1241~1250」の編集履歴(バックアップ)一覧に戻る

AOJ1241~1250 - (2012/07/21 (土) 15:54:21) のソース

*1244 Molecular Formula
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1244
簡略化された原子の重さと化学式が与えられるので化学式の重さの総計を答える問題。

再帰下降構文解析で解きます。
英文字がきたら、2文字読めるか1文字読めるか試します。
その次が数字ならその数字分重さを掛けて、数字でないなら重さを単純に足します。
開きカッコがきたら関数を読んでネスト、閉じかっこか文字列の終わりに到達したら関数はリターンします。


 #include<stdio.h>
 #include<map>
 #include<string>
 #include<iostream>
 std::map<std::string,int> memo;
 int p;
 std::string A,text;//原子の種類
 bool allOK;
 long long int saiki(){
	std::string str1="",str2="";
	char c;
	long long int bai=0,tAns=0,m=0;
	bool isDegit=false;
	while(p<=text.length()&&allOK==true){
		c=text[p];
		if('0'<=c&&c<='9'){
			bai=bai*10+c-'0';
			isDegit=true;
		}else if(isDegit==true){
			tAns=tAns+m*(bai==0?1:bai);
			bai=0;
			isDegit=false;
		}
		if(c=='('){
			bai=0;
			p++;
			m=saiki();
			isDegit=true;
		}else if(c==')' || c=='\0'){
			return tAns;
		}else if(!('0'<=c&&c<='9')){
			str1=c;
			str2=c;
			m=-1;
			bai=0;
			if(p<text.length()-1){
				str2+=text[p+1];
				if(memo.find(str2)!=memo.end()){
					m=memo[str2];
					p++;
					isDegit=true;
				}else if(memo.find(str1)!=memo.end()){
					m=memo[str1];
					isDegit=true;
				}
			}else if(memo.find(str1)!=memo.end()){
				m=memo[str1];
				isDegit=true;
			}
			if(m==-1)allOK=false;
		}
		if(p<text.length())p++;
	}
	return tAns;
 }
 int main(){
	
	int m;//重さ
	while(1){
		std::cin>>A;
		if(A=="END_OF_FIRST_PART")break;
		std::cin>>m;
		memo[A]=m;
	}
	while(1){
		std::cin>>text;
		if(text=="0")break;
		p=0,allOK=true;
		long long int ans=saiki();
		if(allOK==false)std::cout<<"UNKNOWN\n";
		else std::cout<<ans<<"\n";
	}
 }