刷题荒废了一个多月,今日了却一件事情,把此题补上!

UVa10129

Play on Words

有若干个圆盘,每个圆盘上都有一个单词,判断这些圆盘是否能排成一排,使得相邻圆盘的首尾字母相同。

3年前做过类似的题目,这道题建模非常重要。

最容易想到的是将圆盘看做顶点,圆盘之间首尾字母的关系看做边,若此图中包含一个哈密顿路径,则问题有解。但是哈密顿路径一般只能通过搜索方法求解,且没有办法剪枝,所以会超时。

还有一种办法,就是将圆盘看做边,字母看做顶点,那么只要该图中包含欧拉路径,则问题有解,而欧拉路径是可以剪枝的,首先图需要连通,其次因为要遍历所有的边,所以对顶点的入度和出度有要求,即除欧拉路径的起点和终点外,其余顶点必须是有进有出的,也就是顶点的入度和出度要相等,而对于起点和终点,出度和入度差值为1

#include <iostream>
#include <array>
#include <bitset>
#include <climits>
#include <map>
#include <queue>
#include <string>
#include <vector>using namespace std;struct Vertex
{size_t no;size_t Indegree, Outdegree;Vertex() : no(0), Indegree(0), Outdegree(0) {}
};class Solution
{public:Solution(const vector<string> &plates): TotalEdges(plates.size()), TotalVertex(0),EulerPathStart(UINT_MAX), EulerPathEnd(UINT_MAX){graph.fill(array<size_t, 26>());for (const string &plate : plates){size_t front = plate.front() - 'a', back = plate.back() - 'a';vertexes[front].no = front;vertexes[back].no = back;if (front == back) {TotalEdges--;continue;}graph[front][back]++;vertexes[front].Outdegree++;vertexes[back].Indegree++;}TotalVertex = vertexes.size();}bool solve(){if (!CheckDegree()) return false;if (!CheckConnectivity()) return false;found = false;ArrangePlate(EulerPathStart, TotalEdges);return found;}
private:array<array<size_t, 26>, 26> graph;map<size_t, Vertex> vertexes;size_t TotalEdges, TotalVertex;size_t EulerPathStart, EulerPathEnd;bool found;bool CheckDegree(){for (const pair<size_t, Vertex> &p : vertexes){const Vertex &vertex = p.second;if (vertex.Indegree == vertex.Outdegree) continue;else if (vertex.Indegree + 1 == vertex.Outdegree) {if (EulerPathStart == UINT_MAX) {EulerPathStart = p.first;}else return false;}else if (vertex.Indegree == vertex.Outdegree + 1) {if (EulerPathEnd == UINT_MAX) {EulerPathEnd = p.first;}else return false;}else return false;}if (EulerPathStart == UINT_MAX && EulerPathEnd == UINT_MAX) {EulerPathStart = EulerPathEnd = vertexes.begin()->first;}return EulerPathStart != UINT_MAX && EulerPathEnd != UINT_MAX;}bool CheckConnectivity(){queue<size_t> q;bitset<26> visited(string(26, '0'));size_t remain = TotalVertex - 1;visited.set(EulerPathStart);q.push(EulerPathStart);while (remain != 0 && !q.empty()) {const array<size_t, 26> &adjacents = graph[q.front()];for(size_t j = 0; j < adjacents.size(); j++){if (adjacents[j] != 0 && !visited.test(j)) {remain--;visited.set(j);q.push(j);}}q.pop();}return remain == 0;}void ArrangePlate(size_t curr, size_t LeftEdge){if (LeftEdge == 0) {found = true;return;}array<size_t, 26> &adjacents = graph[curr];for (size_t j = 0; j < adjacents.size(); j++){if (!found && adjacents[j] > 0) {adjacents[j]--;ArrangePlate(j, LeftEdge - 1);adjacents[j]++;}}}
};int main()
{int T;cin >> T;for (int i = 0; i < T; i++){int N;cin >> N;vector<string> plates;for (int j = 0; j < N; j++){string plate;cin >> plate;plates.push_back(plate);}Solution solution(plates);if (solution.solve()) {cout << "Ordering is possible." << endl;}else {cout << "The door cannot be opened." << endl;}}return 0;
}
/*
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
*/

算法竞赛入门经典 例题6-16相关推荐

  1. 古老的密码(Ancient Cipher,UVa1339)(算法竞赛入门经典 例题4-1)C++

    题目:给定两个不超过100的字符串,判断是否可以做到将其中一个字符串通过重排和映射的操作,使得两个字符串相同.例如,JWPUDJSTVP重排后可以得到WJDUPSJPVT,然后每个字母只要通过一次映射 ...

  2. 算法竞赛入门经典 例题6-6 小球下落(python、C)

    同个人网站 https://www.serendipper-x.cn/,欢迎访问 ! 问题描述: 有一颗二叉树,最大深度为D,且所有叶子的深度都相同.所有结点从上到下从左到右编号为 1,2,3,- , ...

  3. 算法竞赛入门经典 例题6-2 铁轨(C、python)

    同个人网站 https://www.serendipper-x.cn/,欢迎访问 ! 问题描述: 某城市有一个火车站,铁轨铺设如图所示.有n节车厢从A方向驶入车站,按进站顺序编号为 1~n .你的任务 ...

  4. 算法竞赛入门经典 例题6-21

    UVa506 System Dependencies 编写程序实现类似Linux下的软件包管理器,其工作方式为: 可以通过命令显式安装组件,这个过程也可能隐式安装依赖组件 如果没有其它组件仍然依赖一个 ...

  5. C++ 刽子手游戏(Hangman Judge, UVa 489)(算法竞赛入门经典例题4-2)

    题目:刽子手游戏是一个简单的猜单词游戏,每次可以猜一个字母,如果单词内有这个字母,此单词内所有该字母都会显示,如果没有该字母,则记一笔错误,若满7笔错误,则输掉()猜已经猜出的单词也算错误).本题编写 ...

  6. Java实现算法竞赛入门经典例题-蚂蚁

    问题描述 一根长度为L厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米/秒. 当两只蚂蚁相撞时,二者同时掉头(掉头时间忽略不计). 给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂 ...

  7. UVA-814 邮件传输代理的交互 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 #include<iostream> #include< ...

  8. UVA-12171 雕塑 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 这道题目在<算法竞赛入门经典第二版>书中标注了星号,也是第一道出现星号的 ...

  9. UVA-1598 交易所 题解答案代码 算法竞赛入门经典第二版

    GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 AC代码 有意思的一个题目.书上说这是一个不错的优先队列练习题,但实际上它其实是一个 ...

最新文章

  1. 【译】Getting Started With Ethereum and Building Basic Dapp — Part 1
  2. xgboost简单介绍_好文干货|全面理解项目中最主流的集成算法XGBoost 和 LightGBM
  3. mysql 主主结构_高性能mysql主主架构
  4. 谈谈一些有趣的CSS题目(十三)-- 巧妙地制作背景色渐变动画!
  5. 分布式场景下数据一致性的问题——【分布式锁】 Java常用技术方案
  6. Centos 7安装Docker可视化管理面板安装中文Portainer
  7. 免疫算法(matlab)
  8. 夏昕的3部开发手册.- -
  9. matlab求解拉格朗日第一方程,matlab求解拉格朗日方程肿么编程
  10. word选择粘贴没有html格式,Word选择性粘贴怎么用?Word设置无格式文本粘贴快捷键的方法...
  11. IJCAI TEXT PAPERS
  12. 智能眼镜革命:从功能机到智能机,转折点临近
  13. windows10下VM安装安卓虚拟机PhoenixOS
  14. android espresso跨程序,在Espresso Android中正确使用IdlingResource的方法
  15. 关于win10X64 连接oracle
  16. 通达信插件获取并存储通达信商品指数的实时数据
  17. 爬虫实战之全站爬取拉勾网职位信息
  18. 二、计算机网络体系架构——网络工程师成长之路
  19. ​JJKY-30Z检漏继电器
  20. 计算机答疑在线,基于web的在线答疑系统设计

热门文章

  1. Tomcat Connector的BIO与NIO模式的比较及区别
  2. Excel区间数据拆分
  3. mysql的密码破解
  4. DOS环境下出现“ ‘javac‘不是内部或外部命令,也不是可运行的程序或皮处理文件 “的报错的解决方法
  5. ubuntu rsync 命令拷贝,显示进度
  6. 机器学习——支持向量机(SVM)之超平面、间隔与支持向量
  7. Apollo planning之PiecewiseJerkPathOptimizer
  8. 最佳实践 | 用腾讯云AI人像变换给自己一次“跨越年龄的体验”
  9. Python将Excel文件插入Mysql数据库(脚本)
  10. 学5G网络优化,就业前景好?薪资高?