# 程序控

IPPP (Institute of Penniless Peasent-Programmer) Fellow

:: :: :: :: :: :: :: ::
 77 随笔 :: 0 文章 :: 459 评论 :: 0 引用

Time limit: 3.000 seconds

## Background背景

Order is an important concept in mathematics and in computer science. For example, Zorn's Lemma states: "a partially ordered set in which every chain has an upper bound contains a maximal element." Order is also important in reasoning about the fix-point semantics of programs.

This problem involves neither Zorn's Lemma nor fix-point semantics, but does involve order.

## The Problem问题

Given a list of variable constraints of the form x < y, you are to write a program that prints all orderings of the variables that are consistent with the constraints.

For example, given the constraints x < y and x < z there are two orderings of the variables x, y, and z that are consistent with these constraints: x y z and x z y.

## The Input输入

The input consists of a sequence of constraint specifications. A specification consists of two lines: a list of variables on one line followed by a list of constraints on the next line. A constraint is given by a pair of variables, where x y indicates that x < y.

All variables are single character, lower-case letters. There will be at least two variables, and no more than 20 variables in a specification. There will be at least one constraint, and no more than 50 constraints in a specification. There will be at least one, and no more than 300 orderings consistent with the contraints in a specification.

Input is terminated by end-of-file.

## The Output输出

For each constraint specification, all orderings consistent with the constraints should be printed.

Orderings are printed in lexicographical (alphabetical) order, one per line.

Output for different constraint specifications is separated by a blank line.

a b f g
a b b f
v w x y z
v y x v z v w v

abfg
abgf
agbf
gabf

wxzvy
wzxvy
xwzvy
xzwvy
zwxvy
zxwvy

## Solution解答

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
//主函数
int main(void) {
bool bFirst = true;
char szOrder[24];
//循环读取并处理每一个组原字符串和约束
for (string str; getline(cin, str); bFirst = false) {
//为加快速度，便于处理，将原字符串转存到数组中
strcpy(szOrder, str.c_str());
//去掉原字符串中间的空格
int nLen = remove(szOrder, &szOrder[str.size()], ' ') - szOrder;
szOrder[nLen] = '\0';
//获取约束串
getline(cin, str);
//去掉约束串中间的空格
str.erase(remove(str.begin(), str.end(), ' '), str.end());
//生成约束关系表，如果存在约束i > j，则aCompMat[i][j]为true
bool aCompMat[26][26] = {0};
for (string::iterator i = str.begin(); i != str.end(); i += 2) {
aCompMat[*i - 'a'][*(i + 1) - 'a'] = true;
}
//将原字符串从大到小排序，准备生成全排列
sort(&szOrder[0], &szOrder[nLen]);
//如果不是第一次，要按要求在第一行输出一个回车
if (!bFirst) {
cout << endl;
}
//bFlag为false表示发现该顺序不满足约束。每次生成下一组全排列
for (bool bFlag = true; bFlag; bFlag = next_permutation(
&szOrder[0], &szOrder[nLen])) {
//循环判断当前生成的顺序中是否每一对字符都满足约束
for (int i = 0; i < nLen - 1 && bFlag; ++i) {
for (int j = i + 1; j < nLen && bFlag; ++j) {
//出现逆序，即aCompMat[j][i] = true，即不满足
bFlag &= !aCompMat[szOrder[j] - 'a'][szOrder[i] - 'a'];
}
}
//如果全满足约束，则输出有序集
if (bFlag) {
cout << szOrder << endl;
}
}
}
return 0;
}

posted on 2010-08-17 00:56  Devymex  阅读(1442)  评论(0编辑  收藏