Sorting It All Out(关系判断排序算法)
来源:互联网 发布:哇嘎无法连接网络 编辑:程序博客网 时间:2024/06/01 15:48
今天的题目是英文,如果懒得看的可以直接看下面我凭借过了大学英语32级的水平的精简翻译。
Description(题目描述)
An ascending sorted sequence of distinct values is one in which some form of aless-than operator is used to order the elements from smallest to largest. Forexample, the sorted sequence A, B, C, D implies that A < B, B < C and C< D. in this problem, we will give you a set of relations of the form A <B and ask you to determine whether a sorted order has been specified or not.
Input
Input consists of multiple problem instances. Each instance starts with a linecontaining two positive integers n and m. the first value indicated the numberof objects to sort, where 2 <= n <= 26. The objects to be sorted will bethe first n characters of the uppercase alphabet. The second value m indicatesthe number of relations of the form A < B which will be given in thisproblem instance. Next will be m lines, each containing one such relationconsisting of three characters: an uppercase letter, the character"<" and a second uppercase letter. No letter will be outside therange of the first n letters of the alphabet. Values of n = m = 0 indicate endof input.
Output
For each problem instance, output consists of one line. This line should be oneof the following three:
Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.
where xxx is the number of relations processed at the time either a sortedsequence is determined or an inconsistency is found, whichever comes first, andyyy...y is the sorted, ascending sequence.
输入样例
4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0
输出样例
Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
题目出处:
http://www.programfan.com/acm/show.asp?qid=114题目翻译:
会给出两个数字,前面一个数字N表示有几个待排序元素,后面一个数字M表示有几个关系。
输出三种情况:
1. 第M对关系能得出个数字的唯一排序:12345…
2. 第X对序列与之前的X-1对序列出现矛盾
3. 排序序列不唯一
问题分析:
判断三种输出结果的条件如下
1. 关系加入关系集合
2. 如果加入关系时发生矛盾,则矛盾,第几个关系出现矛盾也很好判断。
3. 从最小元素开始遍历,如果最长路径包含所有元素,则序列唯一
现在的问题就是:如何整合呢?
运用某种集合S存储已排序序列(只需要表示相对关系,不需要表示绝对关系),每次添加一个新关系进入集合S
虽然说题设假设只有小于号,但是即使没有这样的提设,我们也应该把符号统一,这样编程会很方便。
对于这种元素之间有先后关系,且可能存在多个直接后继的数据结构(因为本题存在不能确定的情况,在不能确定的情况时后继和前驱都可能是多个),我们可以用AOV网来存储这种集合关系(类似的思路还有这道题:http://blog.csdn.net/ganze_12345/article/details/42780275)。(当然,用树也可以,但是如果用树会有大量的重复节点的副本存在,这是没必要的。)同时用一个一维26位的数组来计入已经加入集合的元素值。
这样一来:如果新的加入关系的两个元素都在AVO网中,一定会出现矛盾或者已经相关。
大者如果在小者的大者集合中,则是一个已经存在的关系,如果不是则一定矛盾。者是如果新加入的关系中有含未加入的元素,则一定是一种新关系,把这种新关系加入AOV网。
这样一来可以开始编程了….
#include <iostream>#include <set>#include <stack>#include <limits>#include <memory>#include <algorithm>#include <iterator>#include <string>#include <list>using namespace std;class Node;class Relation;typedef shared_ptr<Node> NodePtr;typedef shared_ptr<Relation> RelationPtr;class Node{//节点friend ostream& operator << (ostream &, const Node &);friend class Relation;private:char value;public:enum{MINVALUE = CHAR_MIN,//标志最小节点值OFFSET = 'A'//CHAR的偏移量};Node() :value(MINVALUE){}Node(char v) :value(v){}bool operator == (const Node& n){return n.value == value;}static bool InputCheck(char v){return v >= 'A' && v <= 'Z';}};ostream& operator << (ostream &out,const Node &n){//重载标准输出流if (n.value)return out << n.value;return out;}class Relation{//关系friend class RelationSet;private:NodePtr less;//当前元素值set<RelationPtr> moreSet;//大者的集合public://参数l表示小者,参数m表示大者Relation(NodePtr l) :less(l){}bool IsInMoreSet(RelationPtr m){bool isIn = false;if (find(moreSet.begin(), moreSet.end(), m) != moreSet.end())//在集合中return true;for (auto itr : moreSet){isIn = isIn || itr->IsInMoreSet(m);}return isIn;}bool CheckNumber(int n, stack<char> & record, int depth = 0){//校验,n来标记当前比较到的节点的大小位置,record来记录路径bool isEqual = false;if (depth == n){//最长路径record.push(this->less->value);return true;}for (auto itr : moreSet){if (isEqual = (isEqual || itr->CheckNumber(n, record, depth + 1))){//在最长路劲上if (depth){//第一个节点是为了编程方便,不入栈record.push(this->less->value);break;}}}return isEqual;}static bool InputChech(char sign){return sign == '<' || sign == '>';}static bool isLessThanSign(char sign){return sign == '<';}};class RelationSet{//关系集合static const char * const resultSet[];//结果集合enum{CERTAIN,//确定序列INCONSISTENCY,//结果是矛盾的UNCERTAIN//不确定};static list<string> resultBuffer;//结果集合的缓存private:bool haveChecked;//已经得出结果了pair<RelationPtr,bool> * record;//记录已经加入的元素的,前者记录元素位置,后者记录元素是否已经加入int elementsNumber;//元素个数int relationsNumber;//关系个数int relationJoin;//已加入关系数量Relation minNode;//最小节点string result;//本关系集的结果pair<RelationPtr, RelationPtr > Parse(const string &expression){//语义分析if (expression.length() == 3){char l = expression[0];char s = expression[1];char m = expression[2];if (Node::InputCheck(l) && Node::InputCheck(m) && Relation::InputChech(s)){if (!Relation::isLessThanSign(s))swap(l, m);//所有的符号都调整为小于号if (!record[l - Node::OFFSET].second)//节点未经添加{record[l - Node::OFFSET].first = RelationPtr(new Relation(NodePtr(new Node(l))));record[l - Node::OFFSET].second = true;}if (!record[m - Node::OFFSET].second)//节点未经添加{record[m - Node::OFFSET].first = RelationPtr(new Relation(NodePtr(new Node(m))));record[m - Node::OFFSET].second = true;}RelationPtr lPtr = record[l - Node::OFFSET].first, mPtr = record[m - Node::OFFSET].first;return pair<RelationPtr, RelationPtr >(lPtr,mPtr);}throw "The of content expression is error";}throw "The length of expression is error";}public:RelationSet(int en,int rn):elementsNumber(en), relationsNumber(rn), minNode(NodePtr(new Node())), relationJoin(0), haveChecked(false){record = new pair<RelationPtr, bool>[en];memset(record, 0, en);}void JoinRelation(const string &expression){if (++relationJoin > relationsNumber)throw "the number of relations is error";auto elementPair = RelationSet::Parse(expression);if (elementPair.second->IsInMoreSet(elementPair.first)){//如果小元素在大元素的子集中,则一定矛盾haveChecked = true;char r[100];sprintf_s(r, resultSet[RelationSet::INCONSISTENCY], relationJoin);result = r;return;}if (haveChecked)//已经得出结果了return;//以上两个判断有先后顺序的原因是在得出唯一序列之后,新加入的关系也有可能导致矛盾,如果这样还是需要否定之前的判断if (find(minNode.moreSet.begin(), minNode.moreSet.end(), elementPair.first) == minNode.moreSet.end())//小元素未加入{minNode.moreSet.insert(elementPair.first);}if (find(minNode.moreSet.begin(), minNode.moreSet.end(), elementPair.second) == minNode.moreSet.end())//大元素未加入{minNode.moreSet.insert(elementPair.second);}elementPair.first->moreSet.insert(elementPair.second);GetResult();//因为需要判断是第几个关系得出的结果,所以每次加入一对结果都判断一次。}const string& GetResult(){if (!haveChecked){//还没有得出结果stack<char> sequence;//序列集合,如果要依据这个序列输出if (minNode.CheckNumber(elementsNumber,sequence)){haveChecked = true;char r[100];sprintf_s(r, resultSet[RelationSet::CERTAIN], relationJoin);result = r;while (!sequence.empty()){result += sequence.top();sequence.pop();}result += '.';}else{result = resultSet[RelationSet::UNCERTAIN];}}return result;}static void InputSet(){//集合输入int m = 0, n = 0;while (scanf_s("%d%d",&m,&n) != EOF && m && n){//如果m或者n为0,则退出RelationSet temp(m, n);for (; n > 0; --n){string expression;cin >> expression;temp.JoinRelation(expression);}RelationSet::resultBuffer.push_back(temp.GetResult());}}static void OutPut(){copy(resultBuffer.begin(), resultBuffer.end(), ostream_iterator<string>(cout, "\n"));resultBuffer.clear();//输出完清空缓存}~RelationSet(){delete[] record;}};const char * const RelationSet::resultSet[] = {"Sorted sequence determined after %d relations:","Inconsistency found after %d relations.","Sorted sequence cannot be determined."};list<string> RelationSet::resultBuffer;int _tmain(int argc, _TCHAR* argv[]){RelationSet::InputSet();RelationSet::OutPut();return 0;}如何过英语32级?考八次四级就行了....
- Sorting It All Out(关系判断排序算法)
- POJ1094 Sorting It All Out(拓扑排序)每输入条关系判断一次
- POJ1094 Sorting It All Out 拓扑排序判大小关系
- POJ 1094 Sorting It All Out 拓扑排序+Floyd算法
- poj1094 Sorting It All Out (拓扑排序)
- Poj1094 Sorting It All Out (拓扑排序)
- POJ1094-Sorting It All Out 拓扑排序
- 拓扑排序Sorting It All Out
- poj1094 Sorting It All Out(拓扑排序)
- POJ1094 Sorting It All Out 拓扑排序
- POJ1094 Sorting It All Out(拓扑排序)
- nyoj349 Sorting It All Out(拓扑排序)
- POJ1094 Sorting It All Out(拓扑排序)
- NYOJ_349 Sorting It All Out 拓扑排序
- poj1094 Sorting It All Out (拓扑排序)
- poj1094 Sorting it all out(拓扑排序)
- poj1094 Sorting It All Out 拓扑排序
- Sorting It All Out(拓扑排序)
- Mockplus:如何调整图标的大小和方向?
- css样式分类
- KMP算法初步理解
- Sqoop1.4.4将MySQL数据库表中数据导入到HBase表中
- wamp下mysql错误提示乱码的解法
- Sorting It All Out(关系判断排序算法)
- PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
- Spark 机器学习-实例演示- K-Means《二》
- 六、Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
- Xcode3.2.5-Xcode5.0版本PK
- Python 输出字典中的组合元素
- Android-Handler的一些思考
- (译)KVO的内部实现
- win8系统安装时2503,2502错误解决办法