题目:给你一些小写字母,以及一些小写字母的偏序对,求出所有满足偏序关系的排列。
分析:图论,搜索,拓扑排序。本体可直接拓扑偏序,这里直接搜索;
利用偏序关系的判断能否到达下一个点即可。
说明:最后一周了,周日就回家了╮(╯▽╰)╭。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; char buf[55],temp[5000]; int map[55][55],space[256],used[55],head[55],save[55]; void dfs(int s, int d, int n) { if (d == n) { for (int i = 0 ; i < n ; ++ i) printf("%c",buf[save[i]]); printf("\n"); return; } for (int i = 0 ; i < n ; ++ i) { int flag = 1; for (int j = 0 ; j < d ; ++ j) if (map[i][save[j]]) { flag = 0;break; } if (flag && !used[i]) { used[i] = 1; save[d] = i; dfs(i, d+1, n); used[i] = 0; } } } int main() { int t = 0; while (gets(buf)) { if (t ++) printf("\n"); memset(space, 0, sizeof(space)); for (int i = 0 ; buf[i] ; ++ i) space[buf[i]] = 1; int count = 0; for (int i = 'a' ; i <= 'z' ; ++ i) if (space[i]) { space[buf[count] = i] = count; count ++; } gets(temp); int number = 0,move = 0; while (temp[move]) { if (temp[move] >= 'a' && temp[move] <= 'z') temp[number ++] = temp[move]; move ++; } memset(map, 0, sizeof(map)); for (int i = 0 ; i < number ; i += 2) { map[space[temp[i]]][space[temp[i+1]]] = 1; map[i][i] = 1; } //查找起始点集合 int size = 0; for (int i = 0 ; i < count ; ++ i) { int flag = 1; for (int j = 0 ; j < count ; ++ j) { if (i == j) continue; if (map[j][i]) { flag = 0;break; } } if (flag) head[size ++] = i; } memset(used, 0, sizeof(used)); for (int i = 0 ; i < size ; ++ i) { used[head[i]] = 1; save[0] = head[i]; dfs(head[i], 1, count); used[head[i]] = 0; } } return 0; }