最近更新于 2024-05-05 14:19
题目
总共有 n 枚硬币,将它摆成阶梯形,第 k 行有 k 枚硬币,找出可形成完整阶梯形的总行数。
测试环境
gcc 9.4.0 – 64位
-no-pie -std=c17 -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Werror=format-security -Wextra -pedantic -Wimplicit-fallthrough -Wsequence-point -Wswitch-unreachable -Wswitch-enum -Wstringop-truncation -Wbool-compare -Wtautological-compare -Wfloat-equal -Wshadow=global -Wpointer-arith -Wpointer-compare -Wcast-align -Wcast-qual -Wwrite-strings -Wdangling-else -Wlogical-op -Wconversion -g -O0 -lm
方法一:迭代
int solution(int n) { int row = 0; while (1) { n -= row; ++row; if (n == row) { break; } else if (n < row) { --row; break; } } return row; }
方法二:解一元二次方程
#include <math.h> /** * @brief 解一元二次方程 * * @param a * @param b * @param c * @param root 置大小为 2 的 double 数组,用于返回最终解 */ void equation(int a, int b, int c, double root[2]) { int delta = b * b - 4 * a * c; if (delta < 0) { return ; } else if (delta == 0) { root[0] = -b / (2 * a); root[1] = root[0]; } else { double sqrt_delta = sqrt(delta); root[0] = (-b + sqrt_delta) / (2 * a); root[1] = (-b - sqrt_delta) / (2 * a); } } /** * @brief 解答排列硬币问题 * * @param n 硬币总数 * @return int 可排列的阶梯行数 */ int solution(int n) { double root[2]; equation(1, 1, -2 * n, root); int i = 0; while (i < 2) { if (root[i] > 0) { break; } ++i; } return (int)root[i]; }
两种方法相对来说,解一元二次方程效率更高,使用迭代的话,随着要求的 fibonacci 数增大,循环的次数越来越多,而解一元二次方程是恒定的,时间复杂度为 O(1)。
排列硬币