東京大学 情報理工学系研究科 コンピュータ科学専攻 2021年8月実施 専門科目 問題2
Author
祭音Myyura, zephyr
Description
C言語で書かれた以下のプログラムは整数配列 a の a[i] から a[j-1] までを昇順に整列する関数 mysort(a, i, j) を定義している (i < j)。 プログラム中の関数 multifrac(k, l, m) は k, l, m が正の整数であるときに 以上の最小の整数を求める関数であり、w, x, y, z は正の整数定数とする。 整数の演算はオーバーフローしないものとする。
int multifrac(int k, int l, int m) {
return (k * l + (m-1))/m;
}
void compare_swap(int *p, int *q) {
if (*p > *q) {
int tmp = *p;
*p = *q;
*q = tmp;
}
}
void mysort(int a[], int i, int j) {
int k = j - i;
if (k < 4) {
[ 空欄 X ]
} else {
mysort(a, i, i + multifrac(k, x, w));
mysort(a, j - multifrac(k, y, w), j);
mysort(a, i, i + multifrac(k, z, w));
}
}
以下の問いに答えよ。
(1) (w, x, y, z) が (4, 3, 3, 3) である場合、空欄 X に入れるべき適切なコードを考えよ。 ただし、compare_swap 以外の関数呼び出しは不可とする。 なお、コードは複数行にわたってもよい。
(2) mysort(a, 0, n) が呼び出された時にコード断片 X が実行される回数の合計を と表記する。 (w, x, y, z) が (4, 3, 3, 3) である場合、 の に関するオーダーを与えよ。
(3) (w, x, y, z) が (4, 2, 3, 3), (4, 3, 2, 3), (4, 3, 3, 2), (4, 2, 3, 2) である場合のそれぞれについて、mysort 関数が常に正しく動作するか否かを答えよ。
(4) mysort が常に正しく動作するために w, x, y, z が満たすべき必要十分条件を答えよ。
题目描述
题中 C 程序定义函数 mysort(a,i,j),用于将整数数组
a[i] 至 a[j-1] 升序排列,其中 。函数
multifrac(k,l,m) 返回
(按整数除法计算); 是正整数常量,整数运算不会溢出。
compare_swap(p,q) 在 *p > *q 时交换两数。mysort 对长度
的区间执行空白代码 ;否则依次递归排序:
回答下列问题。
(1)当 时,写出空白 中的适当代码;除
compare_swap 外不得调用其他函数,代码可有多行。
(2)调用 mysort(a,0,n) 时,记代码片段 的总执行次数为 。
当 时,给出 关于 的渐近阶。
(3)分别对
判断 mysort 是否总能正确排序。
(4)给出使 mysort 对所有输入均正确工作的 的充要条件。
Kai
(1)
if (k == 3) {
compare_swap(&a[i], &a[i+1]);
compare_swap(&a[i+1], &a[i+2]);
compare_swap(&a[i], &a[i+1]);
} else if (k == 2) {
compare_swap(&a[i], &a[i+1]);
} else {
// Do nothing if k == 1, as a single element is already sorted.
}
(2)
When , we have , and .
Hence,
(3)
- Case (4, 2, 3, 3), (4, 3, 2, 3) and (4, 3, 3, 2) works
- (4, 2, 3, 2): not work
(4)
For positive integers , the necessary and sufficient conditions are
Indeed, a recursive length is smaller than for every iff . Also, sorting a prefix of length , a suffix of length , and a prefix of length sorts every length- sequence iff . Here this holds for every when . Conversely, if the latter inequality fails, choose a sufficiently large multiple of ; then the three ceilings sum to less than , so the routine fails on some input.
Knowledge
递归 分治算法 排序算法
解题技巧和信息
- 递归调用的正确性依赖于覆盖和重叠。每个递归调用必须覆盖整个数组段,确保所有元素最终被排序。
- [[时间复杂度#递归算法的时间复杂度 / Time Complexity of Recursive Algorithms|主定理(Master Theorem)]] 是解决递归关系的有力工具,特别是在分析算法复杂度时。
- 对于分治算法,理解各个部分的覆盖范围和重叠部分对于正确性和效率的保证非常重要。
重点词汇
recursive call 递归调用
coverage 覆盖
overlap 重叠
Master Theorem 主定理
complexity analysis 复杂度分析
参考资料
- Introduction to Algorithms, Third Edition, by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Chap. 4.
- Algorithms, Fourth Edition, by Robert Sedgewick and Kevin Wayne, Chap. 2.