第一次应聘实习 | 排列与阶乘进制
昨天去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; }