地址  https://algospot.com/judge/problem/read/WORDCHAIN

解答:

1 书上的解法是制作有向图 然后查找欧拉回路  代码实现稍后

假设一定存在欧拉路径的做法

 #include <iostream>
#include <vector>
#include <string>
#include <algorithm> using namespace std; vector<vector<int>> adj; vector<string> graph[][]; vector<int> indegree, outdegree; void makeGraph(const vector<string>& words)
{
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
graph[i][j].clear();
adj = vector<vector<int>>(, vector<int>(, ));
indegree = outdegree = vector<int>(, );
for (int i = ; i < words.size(); i++) {
int a = words[i][] - 'a';
int b = words[i][words[i].size() - ] - 'a';
graph[a][b].push_back(words[i]);
adj[a][b]++;
outdegree[a]++;
indegree[b]++;
}
} void getEulerCircuit( int here,vector<int>& circuit )
{
for (int there = ; there < adj.size(); ++there) {
while (adj[here][there] > ) {
adj[here][there]--;
getEulerCircuit(there, circuit);
}
} circuit.push_back(here);
} vector<int> getEulerTrailOrCircuit()
{
vector<int> circuit; for (int i = ; i < ; i++) {
if (outdegree[i] == indegree[i] + ) {
getEulerCircuit(i, circuit);
return circuit;
}
} for (int i = ; i < ; ++i)
{
if (outdegree[i]) {
getEulerCircuit(i, circuit);
return circuit;
}
} return circuit;
} string solve(const vector<string>& words)
{
makeGraph(words); vector<int> circuit = getEulerTrailOrCircuit(); if (circuit.size() != words.size() + ) return "IMPOSSIBLE"; reverse(circuit.begin(), circuit.end());
string ret;
for (int i = ; i < circuit.size(); i++) {
int a = circuit[i - ], b = circuit[i];
if (ret.size()) ret += " ";
ret += graph[a][b].back();
graph[a][b].pop_back();
} return ret;
} int n, m;
int main()
{
cin >> n;
while (n--) {
cin >> m;
vector<string> words;
while (m--) {
string s;
cin >> s;
words.push_back(s);
} cout << solve(words) << endl; } return ;
}

先统计有向图的出入度 判断有无欧拉回路与欧拉路径后 在进行dfs的做法

 #include <iostream>
#include <vector>
#include <string>
#include <algorithm> using namespace std; vector<vector<int>> adj; vector<string> graph[][]; vector<int> indegree, outdegree; void makeGraph(const vector<string>& words)
{
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
graph[i][j].clear();
adj = vector<vector<int>>(, vector<int>(, ));
indegree = outdegree = vector<int>(, );
for (int i = ; i < words.size(); i++) {
int a = words[i][] - 'a';
int b = words[i][words[i].size() - ] - 'a';
graph[a][b].push_back(words[i]);
adj[a][b]++;
outdegree[a]++;
indegree[b]++;
}
} void getEulerCircuit(int here, vector<int>& circuit)
{
for (int there = ; there < adj.size(); ++there) {
while (adj[here][there] > ) {
adj[here][there]--;
getEulerCircuit(there, circuit);
}
} circuit.push_back(here);
} string solve(const vector<string>& words)
{
makeGraph(words); int start = -; int end = -; for (int i = ; i < ; i++) {
if (outdegree[i] != indegree[i]) {
if (outdegree[i] == indegree[i] + ) {
if (- == start)
start = i;
else
return "IMPOSSIBLE";
}
else if (outdegree[i] + == indegree[i] ) {
if( - == end)
end = i;
else
return "IMPOSSIBLE";
}
}
} vector<int> circuit;
if (start == - && end == -) {
for (int i = ; i < ; ++i)
{
if (outdegree[i]) {
getEulerCircuit(i, circuit);
break;
}
}
}
else {
getEulerCircuit(start, circuit);
} reverse(circuit.begin(), circuit.end());
string ret;
for (int i = ; i < circuit.size(); i++) {
int a = circuit[i - ], b = circuit[i];
if (ret.size()) ret += " ";
ret += graph[a][b].back();
graph[a][b].pop_back();
} return ret;
} int n, m;
int main()
{
cin >> n;
while (n--) {
cin >> m;
vector<string> words;
while (m--) {
string s;
cin >> s;
words.push_back(s);
} cout << solve(words) << endl; } return ;
}

2 个人觉得 可以使用首尾单词作为关键字 去哈希 然后进行哈希查找与DFS结合的搜索 看看最后能否将单词全部使用 代码如下

TLE

 #include <iostream>
#include <vector>
#include <string> using namespace std; int n, m; /*
3
4
dog
god
dragon
need
3
aa
ab
bb
2
ab
cd need dog god dragon
aa ab bb
IMPOSSIBLE
*/ vector<string> ret; void Dfs( int begIdx,vector<vector<vector<string>>>& vvstr)
{
if (ret.size() == m) {
return;
} for (int i = ; i < ; i++) {
for (int j = ; j < vvstr[begIdx][i].size(); j++) {
//选择 nextBegIdx 开头的字母
//如果已经选择过了 则进行下一次尝试
if (vvstr[begIdx][i][j][] == '#')
continue; //开始选择该单词接龙
int nextBegIdx = vvstr[begIdx][i][j].back() - 'a';
ret.push_back(vvstr[begIdx][i][j]);
vvstr[begIdx][i][j][] = '#'; //修改字符串的第一个字符 作为已经被选择的标记 Dfs( nextBegIdx, vvstr); if (ret.size() == m) {
return;
} vvstr[begIdx][i][j][] = 'a'+ begIdx;
ret.pop_back();
break;
}
} } void DfsStart(vector<vector<vector<string>>>& vvstr)
{
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
for (int k = ; k < vvstr[i][j].size(); k++) {
//选中这个单词作为开始
int nextBegIdx = vvstr[i][j][k].back() - 'a';
ret.push_back(vvstr[i][j][k]);
vvstr[i][j][k][] = '#'; //修改字符串的第一个字符 作为已经被选择的标记
Dfs( nextBegIdx,vvstr); if (ret.size() == m) {
return;
} //复原 继续下一次选择
vvstr[i][j][k][] = 'a'+i;
ret.pop_back();
break;
}
}
} } int main()
{
cin >> n;
while (n--) {
cin >> m;
string s; vector<vector<vector<string>>> vvstr(, vector<vector<string>>(, vector<string>()));
ret.clear();
for (int i = ; i < m; i++){
cin >> s;
int beg = s[] - 'a';
int end = s.back() - 'a';
vvstr[beg][end].push_back(s);
}
DfsStart(vvstr);
if(!ret.empty()){
for (int i = ; i < ret.size(); i++) {
cout << ret[i] << " ";
}
}
else {
cout << "IMPOSSIBLE";
}
cout << endl;
} return ;
}

算法问题实战策略 WORDCHAIN的更多相关文章

  1. 算法问题实战策略 PICNIC

    下面是另一道搜索题目的解答过程题目是<算法问题实战策略>中的一题oj地址是韩国网站 连接比较慢 https://algospot.com/judge/problem/read/PICNIC ...

  2. 《算法问题实战策略》-chaper7-穷举法

    关于这一章节<算法实战策略>有一段概述问题,我认为对于编程人员来说非常有价值,故在这里进行如下的摘抄: 构想算法是很艰难的工作.相比大家都经历过,面对复杂的要求只是傻乎乎地盯着显示器,或者 ...

  3. 《算法问题实战策略》-chaper32-网络流

    基本的网络流模型: 在图论这一块初步的应用领域中,两个最常见的关注点,其一时图中的路径长度,也就是我们常说的的最短路径问题,另一个则是所谓的“流问题”. 流问题的基本概念: 首先给出一张图. 其实所谓 ...

  4. 《算法问题实战策略》-chaper13-数值分析

    这一章节主要介绍我们在进行数值分析常用的二分.三分和一个近似求解区间积分的辛普森法. 首先介绍二分. 其实二分的思想很好理解并且笔者在之前的一些文章中也有所渗透,对于二次函数甚至单元高次函数的零点求解 ...

  5. 《算法问题实战策略》——chaper9——动态规划法技巧

    Q1: 数字游戏: 两个人(A.B)用n个整数排成的一排棋盘玩游戏,游戏从A开始,每个人有如下操作: (1)    拿走棋盘最右侧或者最左侧的棋子,被拿走的数字从棋盘中抹掉. (2)    棋盘中还剩 ...

  6. 《算法问题实战策略》-chaper8-动态规划法

    Q1:偶尔在电视上看到一些被称为“神童”的孩子们背诵小数点以后几万位的圆周率.背诵这么长的数字,可利用分割数字的方法.我们用这种方法将数字按照位数不等的大小分割后再背诵. 分割形式如下: 所有数字都相 ...

  7. 《算法问题实战策略》-chaper21-树的实现和遍历

    这一章节开始介绍一个数据结构中的一个基本概念——树. 我们从数据结构的解读来解释树结构的重要性,现实世界的数据除了最基本的线性结构(我们常用队列.数组和链表等结构表征),还有一个重要的特性——层级结构 ...

  8. 算法问题实战策略 QUADTREE

    地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...

  9. 算法问题实战策略 DICTIONARY

    地址 https://algospot.com/judge/problem/read/DICTIONARY 解法 构造一个26字母的有向图 判断无回路后 就可以输出判断出来的字符序了 比较各个字母的先 ...

随机推荐

  1. 当Python遇上AI(一)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.什么是学习 如果要给学习下一个定义,那么根据某百科给出的定义是——学习,是指通过阅读.听讲.思考和实践等途径获 ...

  2. Docker 常用操作命令

    一. docker安装  方式1 本地安装: 1)下载docker安装文件: 2)执行安装命令  yum localinstall *: 3)安装完之后 重启 systemctl restart do ...

  3. 表单生成器(Form Builder)之mongodb表单数据查询——统计查询求和

    上一篇笔记仅是记录了一下简单的关联查询,根据笔记中的场景:将某一车辆关联的耗损记录全部放在了一个字段当中.不知道现在中有没有这种场景,我们的应用中没有类似的场景,可能我们更关注的是某车辆的总耗损金额和 ...

  4. 对Windows桌面应用程序进行UI自动化测试

    题记:本文简述如何利用appium对Windows桌面应用程序进行UI自动化测试. 所谓UI自动化测试,就是模拟一个用户,对应用程序的UI进行操作,以完成特定场景的功能性集成测试. 要对Windows ...

  5. git 文件补录和别名

    当git当前的版本要有部分忘记提交或新修改的东西包含在已提交(最近一次提交的版本)的版本时,我们可以进行文件补录 命令:git commit --amend -a 1.git log 查看最后一次提交 ...

  6. 从壹开始 [ 学调试 ]║ 轻松实现 PC端+移动端的本地同步联调

    缘起 哈喽!(瞬间就想到了开场白:亲爱的朋友们,我又回来了

  7. PAT 1012 The Best Rank 排序

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...

  8. 【HNOI 2017】礼物

    Problem Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个装饰物,并且每个装饰物 ...

  9. go-爬图片

    go语言爬取图片 注:动态加载出来的爬取不到,或怕取出来图片出错,代码中的网页是可以正常爬取的 package main import ( "fmt" "io" ...

  10. PHP中发送qq邮件

    <?php namespace app\home\logic; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Except ...