题目链接
清算时刻 - Virtual Judge (csgrandeur.cn)
Serval 的元素周期表 - Gym 103478B - Virtual Judge (csgrandeur.cn)
一些话
dfs积累的东西太少了,这种题特征很明显的,有积累的话纯粹是签到
因为这道题和A. Chat room(双指针)_栞那Kanna的博客-CSDN博客很像,都是问元素是否能组成字符串,所以我只能往双指针的方向想了,但是对于“CAL“这类的字符串,先”C“ 后 ”AL“ 还是 先 ”CA“得到的结果是完全不同的,用双指针的话很难写,所以平时多积累些套路才行。
流程
题目给了20个元素,问是否能组成输入的字符串,因为这些元素长短不一,且先后的顺序会对结果造成影响,所以直接把所有可能走一遍,对应的算法是dp和dfs,dp适合用于求最优解,此题没有最优解,所以用dfs
套路
题目有很多选择,可能性很多,且不存在最优解:
用dfs(树状回溯)
在每一步都试验所有的可能,当发现已经找到一种方式或者目前这种方式不可能是结果的时候,退回上一步继续尝试其他可能。很多时候每一步的处理都是一致的,这时候用递归来实现就很自然。
题目有很多选择,可能性很多,且存在最优解:
dp
ac代码
#include <iostream> using namespace std; string f[30] = {"H","HE","LI","BE","B","C","N","O","F","NE", "NA","MG","AL","SI","P","S","CL","AR","K","CA"}; string s; bool flag; void dfs(int depth){ if(depth == s.size()) { flag = true; return; } if(depth != s.size()-1){ string s1 = s.substr(depth,2); for(int j = 0;j < 20;j++){ if(s1 == f[j]) { dfs(depth+2); break; } } } string s2 = s.substr(depth,1); for(int j = 0;j < 20;j++){ if(s2 == f[j]) { dfs(depth+1); break; } } } int main(){ cin >> s; dfs(0); if(flag) cout << "YES" << endl; else cout << "NO" << endl; return 0; }