Chemist's vows - UVALive 6257

12 篇文章 0 订阅
5 篇文章 0 订阅

Chemist’s vows

problem

题意:

给定字符串,判断是否可以从元素周期表中取出元素组成这个字符串。

思路:

可以按照dp的思路来处理。首先忽略元素符号的大小写,将其放入一个set,接着逐字查看字符串最末一字或两字是否可以从周期表中找到对应的元素。如果可以则进行标记,并继续推至字符串中更靠后的位置,直到推至字符串尾。最后查看是否有对应着整个串的标记就可知道该字符串是否可以被化学元素表示出来了。

dp[i] 表示从头开始,长为 i 的字符串可以用化学元素表示;f(in,n) 表示第 in 个字符做为起始点,长为 n 的子串是否可用化学元素表示。由此得到状态转移方程:

dp[i]={dp[i1] and f(i1,1)} or {dp[i2] and f(i2,2)}

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值