题解:P6635 「JYLOI Round 1」箭头调度
本蒟蒻来 水 一篇题解
看到字典序排列,很容易联想到康托展开,那么可能有小蒟蒻要问:什么是康托展开?
康托展开是将n!-1的整数表达式写成 $ a[n−1] \times (n − 1)!+a[n − 2] \times (n − 2)!+...+a[2] \times 2!+a[1] \times 1! $ 的形式,那么排列字符中第k小的字典序就是将k-1利用康托展开后每一位中没有被放置东西过的第a[n-1]的字符。
进行康托展开后就可以利用我们所得到的第k小的字符的排列
再利用下标来求出拓补排序的序列就可以啦,如果当前序列是从前向后☞的,那就可以输出0,否则就说明需要翻转,就输出1。
当然,上面是一种比较标准的做法,想要打点**骗分**运用人类智慧的,请向下看。
测试点一:啥也不输出就可以骗到10分
测试点二:直接枚举找字符,但是复杂度有点超,慎用
测试点三:字典序中第 k 小的拓扑序便是 n 的全排列中字典序第 k小的那个序列啦。
证明比较麻烦,可以参考第一篇题解的大佬,本蒟蒻还没有那个实力:(
测试点四:只要对于上面的结论进行一遍暴力然后连边就可以啦,
#include<bits/stdc++.h>
using namespace std;
int n,m,k,a[10005],b[10005];
int main() {
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
a[i]=i;
}
for(int i=1;i<=k-1;i++){
next_permutation(a+1,a+n+1);
}
for(int i=1;i<=n;i++){
b[a[i]]=i;
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
cout<<(b[u]>b[v]);
}
return 0;
}
"——敬不完美的明天"
"——敬不再沉默的历史,热烈而勇敢的奔赴,和通往所以未来的旅途"
"——敬盛会的邀请函,所有的谎言,和唯一的真相"
"——敬坚忍的岁月,每个悲伤的夜晚,和终将到来的黎明"
"——敬我的过去,现在,未来...和年少时至死不渝的梦"
时钟的指针转过一圈又一圈,但每一天的开始和结束,永远落在「前进」的十二点

浙公网安备 33010602011771号