首页 > 代码库 > 一笔画问题
一笔画问题
CellularDistrict.h
#pragma once#include <stdio.h>#include <stdlib.h>#include <iostream>#include <vector>#include <list>#include <map>#include <algorithm>using namespace std;typedef map<int, int> DUSHUMAP;//结构体tLine表示一条双向的线段typedef struct{ int pot1; int pot2;}tLine;//一笔画出给定图形int OneLineDrawMap (int n, tLine *arrLines, int* aDrawline) ;// 构造度数mapbool BuildMap(int n, tLine* arrLines, DUSHUMAP& mapDuShu);// 是否存在欧拉回路,存在返回truebool IsExistOulaHuiLu(int iJiDian, DUSHUMAP mapDuShu);// 深度优先搜索求解void DepthFirstSearch(int iStartpoint, int n, DUSHUMAP& mapDuShu, list<int>& listPath, vector<tLine>& vecLine);// 判断两点之间存不存在边,存在返回truebool IsLineBetween2Point(int iPointA, int iPointB, vector<tLine> vecLine);void search(int x,int *ans,int **a,int *d,int &m,int n);
CellularDistrict.cpp
#include "CellularDistrict.h"/************************************************************************Description : 一笔画出给定图形Prototype : Input Param : n表示要画的线段的条数 arrLines表示由多条线段组成的图形,由调用者负责指针的分配,释放和保证合法性Output Param : aDrawline输出画线顺序,调用者保证指针合法性,由调用者负责指针的分配,释放和保证合法性Return Value : 成功返回 0 ,失败返回-1/************************************************************************/int OneLineDrawMap (int n, tLine* arrLines, int* aDrawline) { // 构造度数map,key为节点序号,value为该序号的度数 DUSHUMAP mapDuShu; if (!BuildMap(n, arrLines, mapDuShu)) { cout << "insert into mapDuShu failed!" << endl; return -1; } // 奇点个数 int iJiDian = 0; // 判断是否能一笔画 if (!IsExistOulaHuiLu(iJiDian, mapDuShu)) { return -1; } // 选定一个点为起点,欧拉定理,如果有2个点度为奇数,则只能选其中一个作为起点,另一个为终点 int iStartpoint = 1; if (2 == iJiDian) { for (DUSHUMAP::iterator it = mapDuShu.begin(); it != mapDuShu.end(); it++) { if (1 == (it->second) % 2) { iStartpoint = it->first; break; } } } // 边vector vector<tLine> vecLine; for (int i = 0; i < n; i++) { vecLine.push_back(arrLines[i]); } // 路径list list<int> listPath; // 深度优先搜索,递归求解路径 DepthFirstSearch(iStartpoint, n, mapDuShu, listPath, vecLine); // 反序输出 reverse(listPath.begin(), listPath.end()); for (list<int>::iterator it = listPath.begin(); it != listPath.end(); it++) { *aDrawline = *it; aDrawline++; } return 0;}// 构造度数mapbool BuildMap(int n, tLine* arrLines, DUSHUMAP& mapDuShu){ for (int i = 1; i <= n; i++) { std::pair<map<int, int>::iterator, bool> PairRev = mapDuShu.insert(map<int, int>::value_type(i, 0)); if (!PairRev.second) { return false; } } for (int i = 1; i <= n; i++) { int iPort1 = arrLines[i - 1].pot1; int iPort2 = arrLines[i - 1].pot2; for (DUSHUMAP::iterator it = mapDuShu.begin(); it != mapDuShu.end(); it++) { if ((it->first == iPort1) || (it->first == iPort2)) { (it->second)++; } } } // 删除多余的key DUSHUMAP mapTemp(mapDuShu); for (DUSHUMAP::iterator it = mapDuShu.begin(); it != mapDuShu.end(); it++) { if (0 == it->second) { DUSHUMAP::iterator iter = mapTemp.find(it->first); mapTemp.erase(iter); } } mapDuShu = mapTemp; return true;}// 是否存在欧拉回路bool IsExistOulaHuiLu(int iJiDian, DUSHUMAP mapDuShu){ for (DUSHUMAP::iterator it = mapDuShu.begin(); it != mapDuShu.end(); it++) { if (1 == (it->second) % 2) { iJiDian++; } } // 欧拉定理,无向图存在欧拉路的充要条件是恰有0或2个点度为奇数 if ((1 == iJiDian) || (iJiDian > 2)) { return false; } return true;}// 深度优先搜索求解void DepthFirstSearch(int iStartpoint, int n, DUSHUMAP& mapDuShu, list<int>& listPath, vector<tLine>& vecLine){ DUSHUMAP::iterator itValue = mapDuShu.find(iStartpoint); if (0 == itValue->second) { // 当前节点度数为0,加入输出队列 listPath.push_back(iStartpoint); return; } for (int i = 1; i <= (int)mapDuShu.size(); i++) { if (IsLineBetween2Point(iStartpoint, i, vecLine)) { // 已经遍历过的边删掉 vector<tLine>::iterator it = vecLine.begin(); for (; it != vecLine.end(); it++) { if (((iStartpoint == it->pot1) && (i == it->pot2)) || ((i == it->pot1) && (iStartpoint == it->pot2))) { break; } } vecLine.erase(it); // 已经遍历过的节点度数减1 (itValue->second)--; itValue = mapDuShu.find(i); (itValue->second)--; // 递归搜索 DepthFirstSearch(i, n, mapDuShu, listPath, vecLine); } } // 起点最后入队列 listPath.push_back(iStartpoint);}// 判断两点之间存不存在边,存在返回truebool IsLineBetween2Point(int iPointA, int iPointB, vector<tLine> vecLine){ for (vector<tLine>::iterator it = vecLine.begin(); it != vecLine.end(); it++) { if (((iPointA == it->pot1) && (iPointB == it->pot2)) || ((iPointB == it->pot1) && (iPointA == it->pot2))) { return true; } } return false;}
一笔画问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。