嘘~ 正在从服务器偷取页面 . . .

UVA124 Following Orders 题解


UVA124 Following Orders 题解

题目链接:UVA124 Following Orders

题意

顺序是数学和计算机科学中的一个重要概念。例如,佐恩引理(Zorn's Lemma)指出:“一个偏序集合中,每个链都有一个上界,那么该集合中必存在一个极大元素”。顺序在推理程序的不动点语义中也很重要。

这个问题既不涉及佐恩引理,也不涉及不动点语义,但涉及到顺序。给定一组形式为 \(x<y\) 的变量约束,你需要编写一个程序,打印出与这些约束一致的变量排序。

例如,给定约束 \(x<y\)\(x<z\),存在两种与这些约束一致的变量 \(x\)\(y\)\(z\) 的排序:\(x \ y \ z\)\(x \ z \ y\)

输入格式

输入由一系列约束规范组成。每个规范由两行组成:第一行是变量列表,第二行是约束列表。约束由一对变量组成,其中 "\(x y\)" 表示 \(x<y\)

所有的变量都是小写字母,并且只包含一个字符。每个规范中至少会有两个变量,且不超过 20 个变量。每个规范中至少会有一个约束,且不超过 50 个约束。每个规范中与约束一致的排序至少有一个,且不超过 300 种。

输入以文件结束符(end-of-file)终止。

输出格式

对于每个约束规范,应打印与约束一致的所有排序。排序按字典顺序(按字母顺序)逐行打印。

不同约束规范的输出之间用空行分隔。

我一开始想的是建一个图,然后自由跑。后来我发现,这个东西还不如直接暴力枚举呢。。

时间复杂度 \(\mathcal{O}(26^n)\)\(n\) 为变量数

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(35))

char avi[N],vis[N],g[N][N]; int num,ans[N];
bool check(int a,int b)
{
    for(int i = 0; i < a; i++)
        if(g[b][ans[i]]) return false;
    return true;
}
void clear()
{
    num = 0;
    memset(avi, 0, sizeof(avi)); memset(g, 0, sizeof(g));
    memset(vis, 0, sizeof(vis)); memset(ans, 0, sizeof(ans));
}
void dfs(int now)
{
    if(now == num)
    {
        for(int i = 0; i < now; i++) cout << char(ans[i] + 'a');
        return cout << '\n', void(0);
    }
    for(int i = 0; i < 26; i++)
        if(avi[i] && !vis[i] && check(now, i))
        {
            vis[i] = true; ans[now] = i;
            dfs(now + 1); vis[i] = false;
        }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    string str; bool cxy = false;
    while(getline(cin, str))
    {
        if(cxy) { cout << '\n'; }  clear();
        int len = str.size();
        for(int i = 0; i < len; i++)
            if(str[i] != ' ') { ++num; avi[str[i] - 'a'] = true; }
        getline(cin, str); len = str.size();
        for(int i = 0; i < len; i += 4) g[str[i] - 'a'][str[i + 2] - 'a'] = true;
        dfs(0); cxy = true;
    }
    return 0;
}

参考文献

[1] https://www.luogu.com.cn/problem/solution/UVA124


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录