洛谷-DFS-1019-单词接龙-个人AC题解和公共AC题解笔记

学习内容:

  • 预处理
  • 万能头文件
  • string的使用


    话不多说,直奔主题

本人AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 21
#define MAXLENGTH 21
int n;
int length,max_length;
char words[MAXN][MAXLENGTH];
char current_word[1000];
int book[MAXN];
inline void add(int order,int start)//进行单词连接
{book[order]++;int len=strlen(words[order]);while(start<len){current_word[length]=words[order][start];length++;start++;}current_word[length]='\0';
}
inline int match(int order,int start)//检查是否匹配
{//cout<<"match"<<endl;int t=0;int i;int len;for(i=start;i<length;i++,t++){if(current_word[i]!=words[order][t]){return 0;}}len=length-start;return len;
}
inline int check(int order,int word_length)//check
{int flag=0;int start;for(int i=length-1;i>=length+1-word_length;i--){if(current_word[i]==words[order][0]){start=match(order,i);if(start){add(order,start);flag=1;return flag;}}}return flag;
}
inline void dfs()//普通的dfs啊
{char word[1000];int len1;strcpy(word,current_word);len1=strlen(current_word);int len;if(length>max_length){max_length=length;}for(int i=0;i<n;i++){if(book[i]==2){continue;}len=strlen(words[i]);if(!check(i,len)){continue;}dfs();book[i]--;strcpy(current_word,word);length=len1;}return;
}
int main()
{char origin_letter;cin>>n;for(int i=0;i<n;i++){cin>>words[i];}cin>>origin_letter;for(int i=0;i<n;i++){if(words[i][0]!=origin_letter){continue;}memset(book,0,sizeof(book));length=0;strcpy(current_word,words[i]);length=strlen(words[i]);book[i]++;if(length>max_length){max_length=length;}dfs();}cout<<max_length;return 0;
}

自己的思路:看到题目分类是dfs,自然采取dfs作为核心思路,但是对比公共题解,发现可以采取更好的办法,即采取预处理的方法,预处理思路如下:

  1.'龙’的每个部分都是由单词连接而成,那么其实可以拆分成两两单词连接.
  2.所以提前判断两个单词之间是否可以进行连接,用数组存下前单词与后单词之间的叠数,之后操作就变得简单.

附上洛谷题解代码:

#include<cstdio>
#include<iostream>
#include<string>
#include<cmath> 
using namespace std;
int n;//单词数 
string tr[30];//存储字符串 
int yc[30][30];//两个字母的最小重叠部分 
int vis[30];//判断单词使用频率. 
int mt(int x, int y){//mt函数,返回x单词后连接一个y单词的最小重叠部分 bool pp=true; int ky=0;for(int k=tr[x].size()-1;k>=0;k--){//从x单词尾部向前看看最小重叠部分是从哪里开始的,以为因为是倒着来,所以保证是最小的 for(int kx=k;kx<tr[x].size();kx++){if(tr[x][kx]!=tr[y][ky++]){pp=false;break;}}if(pp==true){//如果说当前以k为开头的前一个单词后缀 ,是后面单词的前缀,就马上返回重叠部分。(tr[x].size()-k是找出来的规律)return tr[x].size()-k;        } ky=0;pp=true;//不行就继续}return 0;
}//可能这里有点难理解。可以手动模拟一下
char ch;//开头字母 
int ans=-1;//答案 
int an=0;//每次搜到的当前最长串 
void dfs(int p){//p为尾部单词编号(p的后缀就是“龙”的后缀,因为p已经连接到”龙“后面了)bool jx=false; for(int j=1;j<=n;j++){if(vis[j]>=2) continue;//使用了两次就跳过 if(yc[p][j]==0) continue;//两单词之间没有重合部分就跳过 if(yc[p][j]==tr[p].size() || yc[p][j]==tr[j].size()) continue;//两者存在包含关系就跳过 an+=tr[j].size()-yc[p][j];//两单词合并再减去最小重合部分 vis[j]++;//使用了一次jx=true;//标记一下当前已经成功匹配到一个可以连接的部分 dfs(j); //接上去an-=tr[j].size()-yc[p][j];//回溯,就要再减回去那一部分长度 vis[j]--;//回溯,使用-- }if(jx==false){//jx==false说明不能再找到任何一个单词可以相连了 ans=max(ans,an);//更新ans }return;
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++)cin>>tr[i];cin>>ch; for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){yc[i][j]=mt(i,j); }}//预处理yc数组。yc[i][j]就表示,i单词后连接一个j单词的最小重叠部分 //比如 i表示at,j表示att. yc[i][j]就为2 但是yc[j][i]就为0.//预处理是一个关键for(int i=1;i<=n;i++){//从头到尾看一下有没有以指定开头字母为开头的单词 if(tr[i][0]==ch){//如果有,就以当前单词为基准进行搜索。 vis[i]++;//使用过一次 an=tr[i].size();//更新当前串长度 dfs(i);//接上vis[i]=0;//消除影响 } } printf("%d",ans);return 0;
}

相比起来,自己的代码采取的是边选取边判断的思路,明显使代码变得冗余,所以预处理这里是一个优化的点.

这里有个隐性的问题需要提到,比如单词A为"abcd",单词B为"defgh",单词c为abcdefghijk,如果仅是两两单词之间判断是否可以连接的话,那么明显可以采取的方式只有AB,AC,但是如果’龙’是AB,即"abcdefgh",那么这时候C可以连在龙尾,即ABC,而如果二二单词连接而成的话,BC是不允许的,但是考虑到采取ABC连接和AC连接,最后的效果是一样的,而且AC连接还可以省出一个B,可能可以为后面的’龙’添加长度,所以AC更加,这在无形中使得二二连接方式直接省略这一步的考虑,因洛谷题解未提出,因防止有人有相同疑问,故在此讲解

此外,说一下题解二,先附上代码

#include<bits/stdc++.h>
using namespace std;
string str[20];
int use[20], length = 0, n;
int canlink(string str1, string str2) {for(int i = 1; i < min(str1.length(), str2.length()); i++) {//重叠长度从1开始,直到最短的字符串长度-1(因为不能包含)int flag = 1;for(int j = 0; j < i; j++)if(str1[str1.length() - i + j] != str2[j]) flag = 0;//逐个检测是否相等if(flag) return i;//检测完毕相等则立即return}return 0;//无重叠部分,返回0
}
void solve(string strnow, int lengthnow) {length = max(lengthnow, length);//更新最大长度for(int i = 0; i < n; i++) {if(use[i] >= 2) continue;//该字符串使用次数需要小于2int c = canlink(strnow, str[i]);//获取重叠长度if(c > 0) {//有重叠部分就开始dfsuse[i]++;solve(str[i], lengthnow + str[i].length() - c);use[i]--;}}
}
main() {cin >> n;for(int i = 0; i <= n; i++) use[i] = 0, cin >> str[i];//str[n]为开始字符 solve(' '+str[n], 1);//有必要解释一下开始阶段。为了指定第一个字符,而且因为canlink需要重叠部分小于最短长度-1,所以要从前面添加一个无意义充长度的‘ ’。这样就强制了canlink函数比较最后一位。cout << length ;
}

对于题解二,第一眼看到就很惊艳,自己代码长的一批,对题解中答主注释的追求简洁的态度很是认同,同时此题采用的也是预处理的操作,然后就是学到的几点:

  • 万能头文件:bits/stdc++.h
  • string数据类型的一些使用
    • 方法:length()
    • 和其他语言类似的’+'来连接string

在这里提一嘴,倒数第三行中的’ ‘就像答主说的因为canlink函数中的重叠长度为最小长度减一,所以这里得放一个’ ‘来占长度,但是我觉得这个操作mmm,跟题解评论一样,显得可读性太差,不如加一个判断来得到’龙头’,个人意见,不喜勿喷

后面题解思路接近,END.

 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言中x的n次方怎么表示_线性代数的本质及其在人工智能中的应用

线性代数是 AI 专家必须掌握的知识&#xff0c;这已不再是个秘密。如果不掌握应用数学这个领域&#xff0c;你永远就只能是「门外汉」。当然&#xff0c;学习线性代数道阻且长。数学&#xff0c;尤其是线性代数常与枯燥、复杂和毫无意义的事物联系起来。不过你还可以另辟蹊径。…

js之箭头函数

原文 ES6标准新增了一种新的函数&#xff1a;Arrow Function&#xff08;箭头函数&#xff09;。 为什么叫Arrow Function&#xff1f;因为它的定义用的就是一个箭头&#xff1a; x > x * x 上面的箭头函数相当于&#xff1a; function (x) {return x * x; } 箭头函数相当于…

android开发蓝牙是否可见开关_如何从后台开启android蓝牙的可见性以及始终保持可见性...

最近工作中遇到一个特殊的需求&#xff0c;要求代码能够从后台开机android手机蓝牙的可见性。而framework提供了一种打开可见性的操作&#xff0c;就是通过向用户弹出一个提示框&#xff0c;来询问是否允许开启可见性。而且限制了最长时间为300秒&#xff0c;代码如下&#xff…

洛谷-DFS-1101-单词方阵-个人AC题解及公共题解的笔记

先上自己AC代码(博主这个代码修改过多次,只因代码长度过长) #include<bits/stdc.h> using namespace std; #define MAXN 102 int flag; int n; int next1[8][2]{{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; char map1[MAXN][MAXN],map2[MAXN][MAXN]; cons…

django 实现电子支付功能

思路&#xff1a;调用第三方支付 API 接口实现支付功能。本来想用支付宝来实现第三方网站的支付功能的&#xff0c;但是在实际操作中发现支付宝没有 Python 接口&#xff0c;网上虽然有他人二次封装的的 Python 接口&#xff0c;但是对我这个小白白来说上手还是有点难度&#x…

android中怎么保存checkbox中的checked属性_第二十四天HTML中的form表单

form表单用于收集用户信息&#xff0c;如&#xff1a;登录、注册等场景&#xff1b;所有要提交的数据都必须放在form标签中action&#xff1a;提交地址、动作&#xff0c;与input标签中typy标签的submit属性相关联。 &#xff0c;提交地址是action的地址method:提交方法&#x…

Python中曲率与弯曲的转换_1000R曲率更具沉浸感!三星T55曲面显示器评测

在曲面屏的设计上&#xff0c;三星一直在突破极限&#xff0c;比如在2017年推出的49英寸超宽带鱼屏C49HG90&#xff0c;引来众人围观&#xff0c;非常震撼。而在曲率方面&#xff0c;我们常见的有1800R和1500R&#xff0c;但是三星并不满足&#xff0c;于日前推出了一款曲率达到…

树的遍历-Preorde Traversal,Inorder Traversal,Postoder Traversal

上代码(创建树,先序,中序,后序) #include<bits/stdc.h> using namespace std; typedef struct TreeNode *BinTree; struct TreeNode {BinTree left,right;int value; }; BinTree CreateTree() {BinTree T;int value;cin>>value;if(value0) //如果输入0,则创…

opencv resize_opencv-python库基础操作(一)

点赞再看&#xff0c;养成习惯&#xff01;点赞再看&#xff0c;养成习惯&#xff01;点赞再看&#xff0c;养成习惯&#xff01;opencv-python库基础操作0.安装opencv-pythonpip install opencv-python进行下载并安装不过在python中导入opencv库的时候需要"import cv2&qu…

Page object设计模式

网上看了很多文章&#xff0c;充斥了大量代码。理解起来不容易&#xff0c;在此就我的理解谈谈PageObject设计模式到底是什么东西。 所谓的Page object模式&#xff0c;主要是编写不同层级的脚本&#xff0c;然后一层一层的继承来完成对web测试过程进行分解。 首先&#xff1a;…

百旺智能编码_【百旺】票字版开票软件操作指南已为您备好,请查阅!

为确保小规模纳税人继续享受税收优惠政策&#xff0c;请广大用户及时对开票软件进行升级~按照国家税务总局要求&#xff0c;从增值税发票税控开票软件五月补丁开始&#xff0c;将停止对增值税发票税控开票软件(税控盘版)“税”字版(以下简称“税”字版)的软件升级更新服务&…

洛谷-图的遍历-P2661-信息传递

#include <iostream> #include <cstdio> using namespace std; const int N 200010; int n, fa[N], ans 0x3f3f3f3f; int get (int x, int &cnt) { //cnt记录环的长度 cnt ;if (fa[x] x) return x;else return get(fa[x], cnt); } int main () {scanf("…

mysql binlog 备份_做好mysql运维,必须熟练掌握备份和恢复,实战一次不行多来几次...

原文&#xff1a;https://www.toutiao.com/i6855460778359816715/平台&#xff1a;头条作者&#xff1a;程序员不就是0和1一、 备份恢复策略进行备份或恢复操作时需要考虑一些因素&#xff1a;1、确定要备份的表的存储引擎是事务型还是非事务型&#xff0c;两种不同的存储引擎备…

在过程中要正式批准可交付成果_干货!软考高项项目管理知识体系5大过程组47个过程...

现在应该很多小伙伴都在紧张的复习软考中&#xff0c;为了让大家更加高效的复习&#xff0c;今天给大家分享软考高级信息系统项目管理师的考试重点&#xff0c;项目管理知识体系的5大过程组47个过程。考高项的朋友都知道&#xff0c;47个过程是非常重要的&#xff0c;必须要理解…

jquery每次动态加载dom,绑定事件会多一次,

jquery绑定事件,每次动态加载dom,绑定的事件会加1,比如动态加载dom5次,点那个点击事件会弹出5次 解决办法就是在每次绑定之前解绑定. $(.seek-footer .btn1).off(click); // 先解绑 $(.seek-footer .btn1).on(click,function () {}) 再绑定 转载于:https://www.cnblogs.com/ybi…

洛谷P3119

省选难度啊啊啊 经评论区的朋友提醒&#xff0c;代码已订正 先说一下该题思路: 首先,这题并非是求最短路,而是求最长路(最长路常用算法一般是拓扑排序,而我这个蒟蒻还没有学会QAQ) 但是这一题既然标签是连通图,那么肯定要用tarjan,考虑到缩点之后每个缩点都具有一定数量的点数,…

android 组件化_Android 组件化路由框架设计(仿Arouter)

前言在组件化开发中一个必须要面对的问题就是组件间页面跳转&#xff0c;实现的方法有很多&#xff0c;简单的可以通过反射获取&#xff0c;但是比较耗费性能&#xff0c;也可以通过隐式跳转&#xff0c;但是随着页面的增多&#xff0c;过滤条件会随之增多&#xff0c;后期维护…

1668智能下数教程视频_你需要的教程合集更新

最近又收集了一波网络安全资源&#xff0c;在文章最底部。花了将近一天时间整理&#xff0c;只求各位小哥哥能点个在看&#xff0c;分享给身边的朋友。网络安全 --职业发展(渗透的最底部)2019网络安全初识与职业发展https://pan.baidu.com/s/1CAzO8IWxzBj-bOZlJ2eFVg 提取码&am…

关于java中nextline读取空白行的问题

最近在做java作业, 发现了一个问题, 就是nextline其实会接收缓冲区的\r, 使得在程序运行时nextline像是跳过了一样, 其实不然, 它只是读取了上一个enter时的\r, 如我的如下功能代码 public void run() {Scanner scan new Scanner(System.in);int ord, book_order;int flag 0;…

python汉字长度_行中字符串的长度(Python)

我正在尝试将一个.txt文件导入到一些专有软件中&#xff0c;但似乎不断收到一个错误。txt文件的大小几乎是2GB&#xff0c;大约有5600万行。 与制造商交谈后&#xff0c;他们说其中一条线路可能有错误。每一行应该包含一个MD5哈希值&#xff08;32个字符&#xff09;&#xff0…