算法问题实战策略 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字母的有向图 判断无回路后 就可以输出判断出来的字符序了 比较各个字母的先 ...
随机推荐
- 当Python遇上AI(一)
Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.什么是学习 如果要给学习下一个定义,那么根据某百科给出的定义是——学习,是指通过阅读.听讲.思考和实践等途径获 ...
- Docker 常用操作命令
一. docker安装 方式1 本地安装: 1)下载docker安装文件: 2)执行安装命令 yum localinstall *: 3)安装完之后 重启 systemctl restart do ...
- 表单生成器(Form Builder)之mongodb表单数据查询——统计查询求和
上一篇笔记仅是记录了一下简单的关联查询,根据笔记中的场景:将某一车辆关联的耗损记录全部放在了一个字段当中.不知道现在中有没有这种场景,我们的应用中没有类似的场景,可能我们更关注的是某车辆的总耗损金额和 ...
- 对Windows桌面应用程序进行UI自动化测试
题记:本文简述如何利用appium对Windows桌面应用程序进行UI自动化测试. 所谓UI自动化测试,就是模拟一个用户,对应用程序的UI进行操作,以完成特定场景的功能性集成测试. 要对Windows ...
- git 文件补录和别名
当git当前的版本要有部分忘记提交或新修改的东西包含在已提交(最近一次提交的版本)的版本时,我们可以进行文件补录 命令:git commit --amend -a 1.git log 查看最后一次提交 ...
- 从壹开始 [ 学调试 ]║ 轻松实现 PC端+移动端的本地同步联调
缘起 哈喽!(瞬间就想到了开场白:亲爱的朋友们,我又回来了
- PAT 1012 The Best Rank 排序
To evaluate the performance of our first year CS majored students, we consider their grades of three ...
- 【HNOI 2017】礼物
Problem Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她.每个手环上各有 \(n\) 个装饰物,并且每个装饰物 ...
- go-爬图片
go语言爬取图片 注:动态加载出来的爬取不到,或怕取出来图片出错,代码中的网页是可以正常爬取的 package main import ( "fmt" "io" ...
- PHP中发送qq邮件
<?php namespace app\home\logic; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Except ...