第一次应聘实习 | 排列与阶乘进制
昨天去ND面试 (车上收到有道短信 说下午视频答疑,估计也没什么问题问的就算了 .主考官直接问我什么时候有时间过去 (囧。然后说暑假吧,直接被他否决了 ,说是不能那么晚,现在就得去,平时没时间可以请假一个星期有到三四天就行了...就这样默默地答应了。之后回来打电话给我说明天要过去签协议,补贴方面800保障,出勤好的话每个月加80(可是网上说是1100,这里怎么变了呢 ,他解释什么税收管理费等(= =不是2k以上才要税收吗,显然地有猫腻...被人坑的感觉自然不爽加上路途漫漫(温泉路口 所以今天一大早打电话过去说不去了 酱紫第一次很山寨的笔试面试经历结束了...
回来继续复习和整理算法。发现模板的《排列与阶乘进制》有猫腻,大牛的代码写的很玄乎看不出是不是真的错了(
代码不能多几个注释嘛,然后按自己的想法改动了跑了一下果然假想没错
现在就说说Coding吧,之前排列与顺序等问题直接都是土土地写地,看了阶乘进制赞叹Knuth大师的伟大(... 然后再看逆过程无比纠结(反正死活看不懂喽,然后偷偷暗想他Coding有问题吧,越看越有问题(= = 鄙视一下自己,经过简单数据验证还好真的是模板的问题(XD
原先的逆过程:
void back(__int64 perm)
{
int i, j, k, p[N + 1] = {0},mark[N + 1] = {0};
i = 1;
while (perm)
{
p[i] = perm % (i + 1);
perm /= ++i;
}
for (i = n-1; i >= 1; --i)
{
j = n,k = 0;
while (k <= p[i])
{
if (!mark[j++])
k++;
}
j++;
a[j] = i + 1;
mark[j] = 1;
}
j = 1;
while (mark[j])
j++;
a[j] = 1;
}
修改后代码:
void back(__int64 perm)
{
int i, j, k, p[N + 1] = {0},mark[N + 1] = {0};
i = 1;
while (perm)
{
p[i] = perm % (i + 1);
perm /= ++i;
}
for (i = n-1; i >= 1; --i)
{
j = 1,k = 0;
while (k <= p[i])
{
if (!mark[j++])
k++;
}
j--;
a[n-i] = j;
mark[j] = 1;
}
j = 1;
while (mark[j])
j++;
a[N] = j;
}
顺便贴上转化为阶乘进制代码:
int KnuthPEncode()
{
int i,j;
int place = n,e = 0;
for (i = 1; i <= n; ++i)
{
int t = a[i];
e *= place--;
for (j = i+1; j <= n ; ++j)
a[j] < t && e++;
}
return e;
}