本文涉及知识点
组合数学汇总
LeetCode1922. 统计好数字的数目
我们称一个数字字符串是 好数字 当它满足(下标从 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 (2,3,5 或 7)。
比方说,“2582” 是好数字,因为偶数下标处的数字(2 和 8)是偶数且奇数下标处的数字(5 和 2)为质数。但 “3245” 不是 好数字,因为 3 在偶数下标处但不是偶数。
给你一个整数 n ,请你返回长度为 n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对 109 + 7 取余后返回 。
一个 数字字符串 是每一位都由 0 到 9 组成的字符串,且可能包含前导 0 。
示例 1:
输入:n = 1
输出:5
解释:长度为 1 的好数字包括 “0”,“2”,“4”,“6”,“8” 。
示例 2:
输入:n = 4
输出:400
示例 3:
输入:n = 50
输出:564908303
提示:
1 <= n <= 1015
1922 乘法原理
根据例2,最高位可以为0。偶数位:有5种选择;奇数位有4种选择。
奇数位有:n/2,偶数位有:n-n/2。
各位的可能累乘。
代码
核心代码
template<int MOD = 1000000007>
class C1097Int
{
public:
C1097Int(long long llData = 0) :m_iData(llData% MOD)
{
}
C1097Int operator+(const C1097Int& o)const
{
return C1097Int(((long long)m_iData + o.m_iData) % MOD);
}
C1097Int& operator+=(const C1097Int& o)
{
m_iData = ((long long)m_iData + o.m_iData) % MOD;
return *this;
}
C1097Int& operator-=(const C1097Int& o)
{
m_iData = (m_iData + MOD - o.m_iData) % MOD;
return *this;
}
C1097Int operator-(const C1097Int& o)
{
return C1097Int((m_iData + MOD - o.m_iData) % MOD);
}
C1097Int operator*(const C1097Int& o)const
{
return((long long)m_iData * o.m_iData) % MOD;
}
C1097Int& operator*=(const C1097Int& o)
{
m_iData = ((long long)m_iData * o.m_iData) % MOD;
return *this;
}
C1097Int operator/(const C1097Int& o)const
{
return *this * o.PowNegative1();
}
C1097Int& operator/=(const C1097Int& o)
{
*this /= o.PowNegative1();
return *this;
}
bool operator==(const C1097Int& o)const
{
return m_iData == o.m_iData;
}
bool operator<(const C1097Int& o)const
{
return m_iData < o.m_iData;
}
C1097Int pow(long long n)const
{
C1097Int iRet = 1, iCur = *this;
while (n)
{
if (n & 1)
{
iRet *= iCur;
}
iCur *= iCur;
n >>= 1;
}
return iRet;
}
C1097Int PowNegative1()const
{
return pow(MOD - 2);
}
int ToInt()const
{
return m_iData;
}
private:
int m_iData = 0;;
};
class Solution {
public:
int countGoodNumbers(long long n) {
auto i1 = n / 2;
auto i0 = n - i1;
auto ans = C1097Int<>(4).pow(i1)* C1097Int<>(5).pow(i0);
return ans.ToInt();
}
};
单元测试
TEST_METHOD(TestMethod11)
{
auto res = Solution().countGoodNumbers(1);
AssertEx(5, res);
}
TEST_METHOD(TestMethod12)
{
auto res = Solution().countGoodNumbers(4);
AssertEx(400, res);
}
TEST_METHOD(TestMethod13)
{
auto res = Solution().countGoodNumbers(50);
AssertEx(564908303, res);
}
TEST_METHOD(TestMethod14)
{
auto res = Solution().countGoodNumbers(806166225460393);
AssertEx(643535977, res);
}