UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)

题意:给一个元素周期表的元素符号(114种),再给一个串,问这个串能否有这些元素符号组成(全为小写)。

解法1:动态规划

定义:dp[i]表示到 i 这个字符为止,能否有元素周期表里的符号构成。

则有转移方程:dp[i] = (dp[i-1]&&f(i-1,1)) || (dp[i-2]&&f(i-2,2))     f(i,k):表示从i开始填入k个字符,这k个字符在不在元素周期表中。  dp[0] = 1

代码:

//109ms 0KB
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
#define N 50007

string single[25] = {"h","b","c","n","o","f","k","p","s","y","i","w","u","v"};
string ss[130] = {"he","li","be","ne","na","mg",
"al","si","cl","ar","ca","sc","ti","cr","mn",
"fe","co","ni","cu","zn","ga","ge","as","se",
"br","kr","rb","sr","zr","nb","mo","tc","ru",
"rh","pd","ag","cd","in","sn","sb","te","xe",
"cs","ba","hf","ta","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","np","pu","am","cm","bk","cf","es",
"fm","md","no","lr"};

int vis[30][30],tag[30];
int dp[N];
char st[N];

void init()
{
    memset(vis,0,sizeof(vis));
    memset(tag,0,sizeof(tag));
    for(int i=0;i<14;i++)
        tag[single[i][0]-‘a‘] = 1;
    for(int i=0;i<100;i++)
        vis[ss[i][0]-‘a‘][ss[i][1]-‘a‘] = 1;
}

int main()
{
    int t,len,i;
    init();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",st+1);
        len = strlen(st+1);
        memset(dp,0,sizeof(dp));
        dp[0] = 1;
        for(i=0;i<len;i++)
        {
            if(dp[i])
            {
                if(tag[st[i+1]-‘a‘])
                    dp[i+1] = 1;
                dp[i+2] |= vis[st[i+1]-‘a‘][st[i+2]-‘a‘];
            }
        }
        if(dp[len])
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}

解法2:DFS

搜索时循环的是元素周期表的符号个数。详见代码

代码: (306ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
#define N 50007

string ss[130] = {"h","b","c","n","o","f","k","p","s","y","i","w","u","v","he","li","be","ne","na","mg",
"al","si","cl","ar","ca","sc","ti","cr","mn",
"fe","co","ni","cu","zn","ga","ge","as","se",
"br","kr","rb","sr","zr","nb","mo","tc","ru",
"rh","pd","ag","cd","in","sn","sb","te","xe",
"cs","ba","hf","ta","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","np","pu","am","cm","bk","cf","es",
"fm","md","no","lr"};

int vis[N];
int len[140];
char st[N];
int Length;
bool Tag;

void init()
{
    int i;
    for(i=0;i<14;i++)
        len[i] = 1;
    for(i=14;i<114;i++)
        len[i] = 2;
}

void dfs(int u)
{
    if(u == Length)
        Tag = 1;
    if(Tag)
        return;
    for(int i=0;i<114;i++)
    {
        int flag = 1;
        if(u+len[i] <= Length && !vis[u+len[i]])
        {
            for(int j=0;j<len[i];j++)
            {
                if(ss[i][j] != st[u+j])
                {
                    flag = 0;
                    break;
                }
            }
            if(flag)
            {
                vis[u+len[i]] = 1;
                dfs(u+len[i]);
            }
        }
    }
}

int main()
{
    init();
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",st);
        Length = strlen(st);
        memset(vis,0,sizeof(vis));
        Tag = 0;
        dfs(0);
        if(Tag)
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}

解法3:乱搞,模拟。

分成: 单个元素存在与否,与前面匹不匹配,与后面匹不匹配,总共2^3 = 8种情况,然后O(n)扫过去,代码很长。。。

代码:(586ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
#define N 50007

string single[25] = {"h","b","c","n","o","f","k","p","s","y","i","w","u","v"};
string ss[130] = {"he","li","be","ne","na","mg",
"al","si","cl","ar","ca","sc","ti","cr","mn",
"fe","co","ni","cu","zn","ga","ge","as","se",
"br","kr","rb","sr","zr","nb","mo","tc","ru",
"rh","pd","ag","cd","in","sn","sb","te","xe",
"cs","ba","hf","ta","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","np","pu","am","cm","bk","cf","es",
"fm","md","no","lr"};

char st[N];
int vis[N];

int main()
{
    int t,len,i,j,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",st);
        len = strlen(st);
        int flag = 1;
        memset(vis,0,sizeof(vis));
        for(i=0;i<len;i++)
        {
            if(vis[i])
                continue;
            string S = "";
            S += st[i];
            for(j=0;j<14;j++)
            {
                if(single[j] == S)
                    break;
            }
            if(j == 14)  //not single
            {
                if(i > 0 && !vis[i-1])
                {
                    S = st[i-1]+S;
                    for(j=0;j<100;j++)
                    {
                        if(ss[j] == S)
                            break;
                    }
                    if(j != 100)  //pre match
                    {
                        if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i] = 0;
                            }
                            else   //back not match
                                vis[i] = 1;
                        }
                    }
                    else   //pre not match
                    {
                        if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i+1] = 1;
                            }
                            else   //back not match
                            {
                                flag = 0;
                                break;
                            }
                        }
                        else
                        {
                            flag = 0;
                            break;
                        }
                    }
                }
                else
                {
                    if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i+1] = 1;
                            }
                            else   //back not match
                            {
                                flag = 0;
                                break;
                            }
                        }
                        else
                        {
                            flag = 0;
                            break;
                        }
                }
            }
            else   //single
            {
                if(i > 0 && !vis[i-1])
                {
                    S = st[i-1]+S;
                    for(j=0;j<100;j++)
                    {
                        if(ss[j] == S)
                            break;
                    }
                    if(j != 100)  //pre match
                    {
                        if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i] = 0;
                            }
                            else   //back not match
                                vis[i] = 1;
                        }
                    }
                    else   //pre not match
                    {
                        if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i] = 0;
                            }
                            else   //back not match
                            {
                                vis[i] = 1;
                            }
                        }
                        else
                        {
                            vis[i] = 1;
                        }
                    }
                }
                else
                {
                    if(i < len-1)
                        {
                            string ks = "";
                            ks += st[i];
                            ks += st[i+1];
                            for(k=0;k<100;k++)
                            {
                                if(ss[k] == ks)
                                    break;
                            }
                            if(k != 100)  //back match
                            {
                                vis[i] = 0;
                            }
                            else   //back not match
                            {
                                vis[i] = 1;
                            }
                        }
                        else
                        {
                            vis[i] = 1;
                        }
                }
            }
        }
        if(flag)
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}

UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP),布布扣,bubuko.com

UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)

时间: 2024-10-12 07:40:58

UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)的相关文章

UVALive 6257 Chemist&#39;s vows

1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #include<ctype.h> 5 #include<algorithm> 6 #include<stack> 7 #include<queue> 8 #include<set> 9 #include<math.h> 10 #include<vector>

【算法学习笔记】52.一道题的三种方法..二分答案、动态规划、计算几何 SJTU OJ 1250 BestSubsequence

---恢复内容开始--- 1250. BestSubsequence Description LL有n个妹子,他给妹子们编号排成一排.据说今天天气大好,LL要去春游了,他决定要选定至少F个妹子一起去玩. 为了让妹子们开心,他决定选连续一段的妹子们.然后LL有个特殊的癖好,他喜欢体重比较厉害一些的妹子. 那你可以帮LL选妹子吗,使得选出来的这些妹子的平均体重最大. Input Format 输入第一行两个整数,n和F. 接下来n行,每行一个整数,表示妹子的体重. 对前50%的数据:1<=n<=2

UVAlive 7414 Squeeze the Cylinders a,b,c三种步数 搜索+最短路

You are playing a game with your elder brother.First, a number of circles and arrows connecting some pairs of the circles are drawn on the ground.Two of the circles are marked as the start circle and the goal circle.At the start of the game, you are

一道题采用两种设计模式:对比策略模式和模版方法

摘要 <C++ Primer>习题14.38和14.39分别采用策略模式.模版方法解决问题. 问题 <C++ Primer 5th>习题 14.38 : 编写一个类令其检查某个给定的 string 对象的长度是否与一个阀值相等.使用该对象编写程序,统计并报告输入的文件中长度为 1 的单词有多少个.长度为 2 的单词有多少个........长度为 10 的单词有多少个. <C++ Primer 5th>习题 14.39 : 修改上一题的程序令其报告长度在 1 至 9 之间

洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的方格的列表.你的任务是计算并输出,在他的农场中,不需要砍树却能够修建的最大正方形牛棚.牛棚的边必须和水平轴或者垂直轴平行. EXAMPLE 考虑下面的方格,它表示农夫约翰的农场,‘.'表示没有树的方格,‘#'表示有树的方格 1 2 3 4 5 6 7 8 1 .

[ACM] POJ 1094 Sorting It All Out (拓扑排序)

Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26801   Accepted: 9248 Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from sm

NUC_TeamTEST_C &amp;&amp; POJ2299(只有归并)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 42627   Accepted: 15507 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

字符替换问题

问题描述:输入两个字符串str1和p,将str1中的某个字符替换为字符串p. 分析:这个问题其实就是编程语言里的字符替换库函数,我们需要自己去实现,需要找出一种高效的办法,对于这道题存在两种解法. 解法一:从头开始扫描字符串str1,每次遇到空格后,插入字符串P,再插入字符串P之前,需要先将空格后面的字符往后挪位,然后在将P插入即可. 此方法很直观,也很容易想到,但是时间复杂度却达到了O(n^2),效率很低. 解法二:从尾到头扫描,刚看到这里读者会以为是一样的,只不过是从后面开始而已,其实不然,

poj 1094 Sorting It All Out 拓补排序

Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D.