算法问题实战策略 WORDCHAIN
地址 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的更多相关文章
- 算法问题实战策略 PICNIC
下面是另一道搜索题目的解答过程题目是<算法问题实战策略>中的一题oj地址是韩国网站 连接比较慢 https://algospot.com/judge/problem/read/PICNIC ...
- 《算法问题实战策略》-chaper7-穷举法
关于这一章节<算法实战策略>有一段概述问题,我认为对于编程人员来说非常有价值,故在这里进行如下的摘抄: 构想算法是很艰难的工作.相比大家都经历过,面对复杂的要求只是傻乎乎地盯着显示器,或者 ...
- 《算法问题实战策略》-chaper32-网络流
基本的网络流模型: 在图论这一块初步的应用领域中,两个最常见的关注点,其一时图中的路径长度,也就是我们常说的的最短路径问题,另一个则是所谓的“流问题”. 流问题的基本概念: 首先给出一张图. 其实所谓 ...
- 《算法问题实战策略》-chaper13-数值分析
这一章节主要介绍我们在进行数值分析常用的二分.三分和一个近似求解区间积分的辛普森法. 首先介绍二分. 其实二分的思想很好理解并且笔者在之前的一些文章中也有所渗透,对于二次函数甚至单元高次函数的零点求解 ...
- 《算法问题实战策略》——chaper9——动态规划法技巧
Q1: 数字游戏: 两个人(A.B)用n个整数排成的一排棋盘玩游戏,游戏从A开始,每个人有如下操作: (1) 拿走棋盘最右侧或者最左侧的棋子,被拿走的数字从棋盘中抹掉. (2) 棋盘中还剩 ...
- 《算法问题实战策略》-chaper8-动态规划法
Q1:偶尔在电视上看到一些被称为“神童”的孩子们背诵小数点以后几万位的圆周率.背诵这么长的数字,可利用分割数字的方法.我们用这种方法将数字按照位数不等的大小分割后再背诵. 分割形式如下: 所有数字都相 ...
- 《算法问题实战策略》-chaper21-树的实现和遍历
这一章节开始介绍一个数据结构中的一个基本概念——树. 我们从数据结构的解读来解释树结构的重要性,现实世界的数据除了最基本的线性结构(我们常用队列.数组和链表等结构表征),还有一个重要的特性——层级结构 ...
- 算法问题实战策略 QUADTREE
地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...
- 算法问题实战策略 DICTIONARY
地址 https://algospot.com/judge/problem/read/DICTIONARY 解法 构造一个26字母的有向图 判断无回路后 就可以输出判断出来的字符序了 比较各个字母的先 ...
随机推荐
- 剑指offer笔记面试题1----赋值运算符函数
题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString{ public: CMyString(char* pData = nullptr); CMyS ...
- c++11 auto 与auto& 遍历vector区别
目录 说明 c++11 auto 与auto& 遍历区别 今天被这个问题坑了一天,一直以为是算法错了,debug了一天,最后暴力生成数据才发现,测试代码如下: 说明 转载请注明出处:https ...
- 12C-使用跨平台增量备份减少可移动表空间的停机时间 (Doc ID 2005729.1)
12C - Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup (Doc ID 20057 ...
- java8的捕获多个异常的一个写法
这是按intellij idea的提示知道的, 可以写成 catch(xxxException | yyyException | zzzException e){ } 这样的形式,对几个不同的异常使用 ...
- CALL和RET指令实验
实验10 1.在屏幕8行3列,用绿色显示data段中的字符串 assume cs:code data segment db data ends code segment start: ;行 ;列 ;颜 ...
- java.lang.IllegalStateException: Cannot call sendError() after the response has been committe
1.问题描述 严重: Servlet.service() for servlet [default] in contextwith path [/OxygenCloud] threw exceptio ...
- java学习路线推荐,希望能帮到你
很多小白刚开始学习java时,肯定迷惘过,因为对java基本是啥也不懂的,一直想知道java的具体学习路线,我曾经也看了许许多多的java经验分享的帖子,评论,以及其他各种培训机构所谓的学习路线,特别 ...
- 关于中医的一段对话 [ZZ] -- 思维训练故事
转载自新浪博客 网址: http://blog.sina.cn/dpool/blog/s/blog_9880df4201015khq.html?type=-1 关于中医的一段对话 2013-01-26 ...
- pandas.apply()函数
1.介绍 apply函数是pandas里面所有函数中自由度最高的函数.该函数如下: DataFrame.apply(func, axis=0, broadcast=False, raw=False, ...
- python Json报错json.decoder.JSONDecodeError
近期工作中遇到一个问题,执行json.loads(json_data)时,在json_data中加上tab空格后就报错,不加则不报错 一.json.loads(json_data) 报错json.de ...