Chemist’s vows
题意:
给定字符串,判断是否可以从元素周期表中取出元素组成这个字符串。
思路:
可以按照dp的思路来处理。首先忽略元素符号的大小写,将其放入一个set,接着逐字查看字符串最末一字或两字是否可以从周期表中找到对应的元素。如果可以则进行标记,并继续推至字符串中更靠后的位置,直到推至字符串尾。最后查看是否有对应着整个串的标记就可知道该字符串是否可以被化学元素表示出来了。
令
dp[i]
表示从头开始,长为
i
的字符串可以用化学元素表示;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cctype>
#include <vector>
#include <cstring>
#include <queue>
#include <set>
#include <sstream>
using namespace std;
const int maxn = 5e4+4;
set<string> sset;
int main() {
#ifdef TEST
freopen("test.txt", "r", stdin);
#endif // TEST
string temp = "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 Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn\
Fr Ra Rf Db Sg Bh Hs Mt Ds Rg Cn\
Fl\
Lv La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu\
Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr";
for(int i = 0; i < temp.length(); i++){
temp[i] = tolower(temp[i]);
}
stringstream ss;
ss << temp;
while(ss >> temp){
sset.insert(temp);
}
int n;
string sample;
cin >> n;
bool dp[maxn];
while(n--){
cin >> sample;
int len = sample.length();
memset(dp, 0, sizeof(dp));
if(sset.count(sample.substr(0, 1)))
dp[1] = 1;
dp[0] = true;
for(int i = 2; i <= len; i++){
dp[i] = dp[i-1]&&sset.count(sample.substr(i-1, 1)) || dp[i-2]&&sset.count(sample.substr(i-2, 2));
}
printf(dp[len] ? "YES\n" : "NO\n");
}
return 0;
}