核反应
描述
现在我们有一堆核反应的方程式,但是遗憾的是他们的生成物部分的信息遗失了。好在我们通过以往的资料知道了总共消耗掉的反应物信息。你能根据核反应的原子序数守恒,确定这些信息是否属实?
输入
输入数据可能包含若干组数据。
每组数据由包含两个数N,M的一行开始,N和M分别表示消耗掉的反应物个数和生成物个数。
接下来有两行,第一行有N个数,第二行有M个数,分别表示每个反应物和生成物。
输出
对于每组数据如果信息属实输出”YES”,否则输出”NO”。
输入样例
10 3
Mn Co Li Mg C P F Zn Sc K
Sn Pt Y
2 1
H H
He
2 2
Bk Fm
Cf Es
输出样例
YES
YES
NO
数据规模
所有数据,1<=N,M<=17。
可能用到的元素表:
"H","He","Li","Be","B","C","N","O","F","Ne",
"Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca",
"Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu",
"Zn","Ga","Ge","As","Se","Br","Kr","Rb","Sr",
"Y","Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag",
"Cd","In","Sn","Sb","Te","I","Xe","Cs","Ba",
"La","Ce","Pr","Nd","Pm","Sm","Eu","Gd",
"Tb","Dy","Ho","Er","Tm","Yb","Lu","Hf","Ta",
"W","Re","Os","Ir","Pt","Au","Hg","Tl","Pb",
"Bi","Po","At","Rn","Fr","Ra","Ac","Th","Pa",
"U","Np","Pu","Am","Cm","Bk","Cf","Es","Fm"
第一组样例的解释:
Mn+C+K->Sn
Co+Zn+Sc->Pt
Li+Mg+P+F->Y
类似于小木棍。
剪枝比较多。
#include <iostream>
#include <algorithm>
#include <map>
#include <cstdio>
#include <string>
std::map<std::string,long> name;
char element[200][10] = {"","H","He","Li","Be","B","C","N","O","F","Ne",
"Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca",
"Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu",
"Zn","Ga","Ge","As","Se","Br","Kr","Rb","Sr",
"Y","Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag",
"Cd","In","Sn","Sb","Te","I","Xe","Cs","Ba",
"La","Ce","Pr","Nd","Pm","Sm","Eu","Gd",
"Tb","Dy","Ho","Er","Tm","Yb","Lu","Hf","Ta",
"W","Re","Os","Ir","Pt","Au","Hg","Tl","Pb",
"Bi","Po","At","Rn","Fr","Ra","Ac","Th","Pa",
"U","Np","Pu","Am","Cm","Bk","Cf","Es","Fm"};
long A[20];
long B[20];
char tmp[10];
bool used[20];
bool flag = false;
long n=1;long m;
void dfs(long u,long l,long r)
{
if (r > m)
{
flag = true;
return;
}
if (u > n)
return;
if (!used[u])
{
if (l + A[u] == B[r])
{
used[u] = true;
dfs(1,0,r+1);
if (flag)
return;
used[u] = false;
return;
}
if (l + A[u] < B[r])
{
used[u] = true;
dfs(u+1,l+A[u],r);
if (flag)
return;
used[u] = false;
}
if (l + A[u] > B[r])
{
return;
}
}
dfs(u+1,l,r);
}
int main()
{
freopen("nuclear.in","r",stdin);
freopen("nuclear.out","w",stdout);
for (long i=1;i<sizeof(element)/sizeof(element[1])+1;i++)
{
name[element[i]] = i;
}
while (scanf("%ld%ld",&n,&m)==2)
{
for (long i=1;i<n+1;i++)
used[i] = false;
if (n < m)
{
printf("NO\n");
continue;
}
long l = 0;
A[0] = B[0] = 0;
for (long i=1;i<n+1;i++)
{
scanf("%s",tmp);
long tmp2 = name[tmp];
l += tmp2;
A[++A[0]] = tmp2;
}
long r = 0;
for (long i=1;i<m+1;i++)
{
scanf("%s",tmp);
long tmp2 = name[tmp];
r += tmp2;
B[++B[0]] = tmp2;
}
if (l - r)
{
printf("NO\n");
continue;
}
std::sort(A+1,A+1+A[0]);
std::sort(B+1,B+1+B[0]);
if (B[1] < A[1] || B[B[0]] < A[A[0]])
{
printf("NO\n");
continue;
}
flag = false;
dfs(1,0,1);
if (flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}