JAVA CCF-201912-3化学式
32959 ワード
私のCCF認証解題ディレクトリへようこそ
タイトルの説明
構想過程.
クラス
読み込まれた文字列はまず係数を読み込む、係数がなければ1 を表す.次の文字が に入る.次の文字が に運ぶ.次の文字が原子である場合、後に数字があるか否かを判断し、数字がある場合、記憶するときはその数字 を乗じなければならない.
数字を読み取るたびに、
最後にすべての原子を結果セットに運ぶ
試験データ:14 H 2+O 2=H 2 O 2+O 2=H 2 O 2+O 2+O 2=H 2 O 2=H 2 O 2+2 H 2 O H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H H H H H 2+2 O H 2+2 H 2 O CaCl 2+2 AgNO 3=Ca(NO 3)2+2+2 AgCl 3 Ba( OH)2+2+2 H 2 H 2 H 2 H 2 O 4 Zn+10 HNO 3=4 Zn(NO 3)2+NH4 NO 3+3 H 2 O 4 Au+8 NaCNN+2 H 2 O+2 O+2 O+O+O+O+O 2=4 Na(Au(Au(CNCNCN2)+4 NaOH 3 H(2 O)=3 HO 2 3(2 O(H)2)2=3(O(H)2)2 2((H)=H 4(2(3(A 1))))=((((1 A)1)2)3)結果:NYYYYYYYYYNYY
コード#コード#
タイトルの説明
構想過程.
HashMap
を使用して、各式が等しいかどうかを確認します.左の式に対応する原子の数は正、右は負です.結果セット内のすべてのkey
が0
である場合、この式が等しいことを示します.クラス
Node
を新設し、カッコ区間ごとの原子数を格納し、父と息子を指す2つのポインタがある.読み込まれた文字列は
=
で切断され、+
で切断され、各化学式について:(
である場合、係数を読み続け、Node
を新規作成し、サブ区間)
である場合、後に数字があるか否かを判断し、数字がある場合はその区間の全ての原子数にその数字を乗じ、その区間の全ての原子数に化学式の係数を乗じ、次に親区間に戻り、子区間の原子を親区間の数字を読み取るたびに、
index
を対応する位置に移動します.最後にすべての原子を結果セットに運ぶ
試験データ:14 H 2+O 2=H 2 O 2+O 2=H 2 O 2+O 2+O 2=H 2 O 2=H 2 O 2+2 H 2 O H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H 2 O H 2+2 H H H H H 2+2 O H 2+2 H 2 O CaCl 2+2 AgNO 3=Ca(NO 3)2+2+2 AgCl 3 Ba( OH)2+2+2 H 2 H 2 H 2 H 2 O 4 Zn+10 HNO 3=4 Zn(NO 3)2+NH4 NO 3+3 H 2 O 4 Au+8 NaCNN+2 H 2 O+2 O+2 O+O+O+O+O 2=4 Na(Au(Au(CNCNCN2)+4 NaOH 3 H(2 O)=3 HO 2 3(2 O(H)2)2=3(O(H)2)2 2((H)=H 4(2(3(A 1))))=((((1 A)1)2)3)結果:NYYYYYYYYYNYY
コード#コード#
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = Integer.parseInt(in.nextLine());//
while ( n-- != 0 ) {
String[] line = in.nextLine().split("=");
HashMap<String, Integer> result = new HashMap<>();//
int val = -1;
for ( String str: line ) {// ,
String[] second = str.split("\\+");
val = val*-1;//
for ( String temp: second ) {// ,
Node node = new Node();
Stack<Integer> preNum = new Stack<>();// ,
preNum.add(getPreNum(temp));
for ( int i = preNum.peek() == -1?0:Integer.toString(preNum.peek()).length(); i < temp.length(); i++ ) {
if ( temp.charAt(i) == '(' ) {//
preNum.add(i+1 < temp.length()?getPreNum(temp.substring(i+1)):1);//
if ( preNum.peek() != -1 ) i += Integer.toString(preNum.peek()).length();// i
Node child = new Node();
node.child = child;
child.parent = node;
node = child;
} else if ( temp.charAt(i) == ')' ) {//
int lastNum = i+1 < temp.length()?getPreNum(temp.substring(i+1)):1;//
if ( lastNum != -1 ) {// i,
i += Integer.toString(lastNum).length();
mulid(node.map, lastNum);
}
node = node.parent;
mulid(node.child.map, preNum.pop());//
res(node.map, node.child.map);//
} else {//
StringBuffer sb = new StringBuffer(temp.charAt(i)+"");
while ( i+1 < temp.length() && Character.isLowerCase(temp.charAt(i+1)) ) {
sb.append(temp.charAt(++i));
}
int lastNum = i+1 < temp.length()?getPreNum(temp.substring(i+1)):1;//
if ( lastNum != -1 ) i += Integer.toString(lastNum).length();//
if ( !node.map.containsKey(sb.toString()) ) node.map.put(sb.toString(), 0);
node.map.put(sb.toString(), node.map.get(sb.toString())+Math.abs(lastNum)*val);// -1, 1
}
}
mulid(node.map, preNum.pop());//
res(result, node.map);//
}
}
boolean flag = true;
for ( String key: result.keySet() ) {
if ( result.get(key) != 0 ) {
flag = false;
break;
}
}
if ( flag ) System.out.println("Y");
else System.out.println("N");
}
}
// , -1.
public static int getPreNum( String str ) {
if ( str.length() > 0 && Character.isDigit(str.charAt(0)) ) {
int i = 0;
for ( ; i < str.length() && Character.isDigit(str.charAt(i)); i++ );
return Integer.parseInt(str.substring(0, i));
} else return -1;
}
//
public static void res( Map<String, Integer> node, Map<String, Integer> data ) {
for ( String key: data.keySet() ) {
if ( !node.containsKey(key) ) node.put(key, 0);
node.put(key, node.get(key) + data.get(key));
}
}
//
public static void mulid( Map<String, Integer> node, int lastNum ) {
lastNum = Math.abs(lastNum);
for ( String key: node.keySet() ) {
node.put(key, node.get(key)*lastNum);
}
}
}
class Node {
HashMap<String, Integer> map = new HashMap<>();//
Node child = null, parent = null;
}