给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m 、 n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1],...,k[m] 。请问 k[1]*k[2]*...*k[m] 可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18 。
由于答案过大,请对 998244353 取模。
数据范围:
进阶:空间复杂度
, 时间复杂度 )
4
4
拆分成 2 个长度为 2 的绳子,2 * 2 = 4
5
6
剪成一个长度为 2 的绳子和一个长度为 3 的绳子,答案为2*3=6
874520
908070737
请问大佬为什么最后一例通不过啊,先取出a每一位的值是0或1,然后计算出每一位的成绩的模,最后在挨个相乘,只有最后一例,100000000000000L过不了,求解
public long cutRope (long number) {
if (number <= 3) return number - 1;
long a = number / 3;
long b = number % 3;
long c = 998244353L;
int[] bits = new int[64];
int i = 0;
while(a > 0)
{
bits[i] = (int)(a % 2);
a /= 2;
i ++;
}
long[] pow = new long[i];
pow[0] = 3;
for(int j = 1; j < i; j ++)
{
pow[j] = pow[j-1] * pow[j-1];
pow[j] %= c;
}
long rus = 1;
for(int j = 0; j < i; j ++)
{
if(bits[j] == 1)
{
rus *= pow[j];
rus %= c;
}
}
if(b == 1)
{
rus = (rus / 3) * 4;
}
else if(b == 2)
{
rus *= 2;
}
rus %= c;
return rus ;
} //这个快速求幂函数很巧妙,算是这个题的一个难点所在,
//想清楚了就容易多了
import java.util.*;
public class Solution {
final int MOD = 998244353;
long pow(long a, long n){
long ans = 1;
while(n>0){
if(n%2 == 1)ans = (ans*a)%MOD;
a = (a*a)%MOD;
n/=2;
}
return ans % MOD;
}
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
public long cutRope (long number) {
// write code here
long result = 0;
if(number <= 3) return number - 1;
if(number % 3 != 1){
if(number % 3 == 0)
result = pow(3,number/3);
if(number % 3 == 2)
result =pow(3,number/3) * 2 % MOD;
}else{
result = pow(3,number/3 - 1) * 4 % MOD;
}
return result;
}
} class Solution: def cutRope(self , number: int) -> int: # write code here a, b = number // 3, number % 3 p = 998244353 if b==0: return self.qiuyu(3, a, p) elif b==1: return self.qiuyu(3, a-1, p) * 4 % p else: return self.qiuyu(3,a,p) * 2 % p def qiuyu(self,x,n,p): res=1 while n>0: if n%2: res = (res * x) % p x = x ** 2 % p n //= 2 return res
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
long long cutRope(long long number) {
// 时间复杂度O(logN),空间复杂度O(1)
if (number <= 3) return number - 1;
if (number % 3 == 0) return Pow(3, number / 3) % MOD;
else if (number % 3 == 1) return Pow(3, number / 3 - 1) * 4 % MOD;
else return Pow(3, number / 3) * 2 % MOD;
}
long long Pow(long long x, long long y) {
long long ans = 1;
while (y) {
if (y % 2 == 1) ans = ans * x % MOD;
x = x * x % MOD;
y /= 2;
}
return ans;
}
long long MOD = 998244353;
};
public class Solution {
public long cutRope (long number) {
// 快速幂(利用上一题的公式法)
// 特殊值
if(number<4)
return number-1;
// 计算指数
long expo = number/3;
// 整除
if(number%3==0)
return fast(expo) % 998244353;
// 余1,凑成4
else if(number%3==1)
return (fast(expo-1)*4) % 998244353;
// 余2,直接返回
else
return (fast(expo)*2) % 998244353;
}
public long fast(long expo){
long product = 3;
long res=1;
while(expo!=0){
// 如果当前权重有
if((expo & 1) == 1){
res = (res * product) % 998244353;
}
// 累乘
product = (product * product) % 998244353;
// 指数右移1位,准备下次处理
expo = expo >>> 1;
}
return res;
}
} package main
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 原动态规划计算量太大 考虑使用快速幂(借助贪心思想)
* 快速幂 相当于 二分 复杂度O(log2(n))
* @param number long长整型
* @return long长整型
*/
func cutRope(n int64) int64 {
// write code here
if n <= 3 {
return n - 1
}
mod := int64(998244353)
if n%3 == 0 {
return fastPow(3, n/3, mod) // 余数为0 所有段长为3
} else if n%3 == 1 { // 余数为1 最后一个段长为1 将长度为3的段+1 保留一个长度为4的段
return (fastPow(3, (n/3)-1, mod) << 2) % mod
} else { // 余数为2
return (fastPow(3, n/3, mod) << 1) % mod
}
}
// base^exp mod Mod
func fastPow(base, exp, mod int64) int64 {
res := int64(1)
for exp > 0 {
if exp%2 == 1 {
res = (res * base) % mod
}
base = (base * base) % mod
exp /= 2
}
return res
}
class Solution: def cutRope(self, n: int) -> int: if n <= 3: return n - 1 a = n // 3 - 1 # 快速幂的指数(已剥离余数3,4,5) b = n % 3 # 最后的余数:3,4,5对应乘3,乘2*2,乘3*2 d, res = 3, 1 # 以3为底 # 快速幂,不断翻倍基底d while a > 0: if a % 2: res = (res * d) % 998244353 d = d ** 2 % 998244353 a //= 2 if b == 0: return (res * 3) % 998244353 if b == 1: return (res * 4) % 998244353 return (res * 6) % 998244353
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
final int MOD = 998244353;
public long cutRope (long number) {
// write code here
if(number == 2){
return 1;
}
if(number == 3){
return 2;
}
if(number % 3 == 0){
return pow(3, number/3);
}else if(number % 3 == 1){
return 2*2*pow(3, (number-4)/3)%MOD;
}else{
return (2*pow(3, (number-2)/3))%MOD;
}
}
//快速幂函数:求a的n次幂
public long pow(long a, long n){
long result = 1;
while(n > 0){
if((n & 1) == 1){
result = (result*a)%MOD;
}
a = (a*a)%MOD;
n>>=1;
}
return result;
}
} class Solution {
int mod=998244353;
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
long long cutRope(long long number) {
// write code here
if(number<4)return number-1;
long long r=number%3;
long long n=number/3;
if(r==1)
{
n--;
return fa(3,n)*4%mod;
}
if(r==0)r=1;
return fa(3,n)*r%mod;
}
long long fa(long long a,long long n)
{
long long ans=1;
while(n){
if(n&1)
ans=(ans*a)%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
}; # -*- coding: utf-8 -*- # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param number long长整型 # @return long长整型 # class Solution: """ 题目: NC287 剪绳子(进阶版) https://www.nowcoder.com/practice/106f666170554379ab1974e5a601e741?tpId=196&tqId=39738&rp=1&ru=/ta/job-code-total&qru=/ta/job-code-total&difficulty=&judgeStatus=&tags=/question-ranking 借鉴: 大神:妙蛙种子呱呱呱、牛客736356489号 算法: 贪心算法 当number <= 3,直接返回number - 1 当number == 4时,返回4 当number >= 5时,能取3先取3,当小于5时,直接取该数 这里需要注意的是: 当number很大时,如果使用如下循环,容易超时。这里考察的另一个知识点就是快速幂运算。 # while number > 4: # 这里需要使用快速幂运算,不然超时 # res = (res * 3) % MOD # number -= 3 # return res * number % MOD 复杂度: 时间复杂度:O(logN) 空间复杂度:O(1) """ def cutRope(self, number): # write code here def fastPow_rec(x, n): # 递归法 if n == 0: return 1 elif n == 1: return x else: part = fastPow_rec(x, n / 2) % MOD if n % 2 == 0: ans = part * part % MOD else: ans = part * part * x % MOD return ans def fastPow_ite(x, n): # 迭代法 if n == 0: return 1 elif n == 1: return x else: ans = 1 while n > 0: if n % 2 == 1: ans *= x % MOD x = x ** 2 % MOD n /= 2 return ans if number <= 3: return number - 1 elif number == 4: return 4 else: res, MOD = 1, 998244353 cnt = number / 3 if number % 3 == 0: res = fastPow_ite(3, cnt) % MOD elif number % 3 == 1: res = fastPow_ite(3, cnt - 1) * 4 % MOD else: # number % 3 == 2 res = fastPow_ite(3, cnt) * 2 % MOD return res if __name__ == '__main__': s = Solution() # n = 4 # n = 5 # n = 874520 n = 999999999 res = s.cutRope(n) print res
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
const long long MOD = 998244353;
long long cutRope(long long n) {
//n > 1, 1 < m <= n
switch (n) {
case 2:
return 1;
case 3:
return 2;
case 4:
return 4;
}
long long t3 = n / 3;
switch (n % 3) {
case 1:
return qPow(3, t3 - 1) * 4 % MOD;
case 2:
return qPow(3, t3) * 2 % MOD;
case 0:
return qPow(3, t3);
default:
return 1;
}
}
long long qPow(long long q, long long k) {
if (k == 0)return 1;
long long now = q, ans = 1;
while (k) {
if (k & 1) {
ans = ans * now % MOD;
}
k >>= 1;
now = now * now % MOD;
}
return ans;
}
};快速幂
import java.util.*;
import java.math.BigDecimal;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param number long长整型
* @return long长整型
*/
public long cutRope (long number) {
// write code here
if (number == 1) return 0;
if (number == 2) return 1;
if (number == 3) return 2;
long num_3 = number / 3;
long num_2 = (number - num_3 * 3) / 2;
long num_1 = (number - num_3 * 3 - num_2 * 2);
if (num_1 == 1) {
num_3--;
num_2 = num_2 + 2;
num_1 = 0;
}
long res = 1;
//(a * b) % mod = (a % mod * b % mod) % mod
res = res * (powCal(3, num_3));
//if (res > 998244353) res = res % 998244353;
res = res * (powCal(2, num_2)) % 998244353;
return res;
}
public long powCal(long a, long b) {
long res = 1;
while (b > 0) {
if ((b & 1) == 1) {
res = res * a % 998244353;
}
a = a * a % 998244353;
b >>= 1;
}
return res;
}
} class Solution:
mod = 998244353
def q_mul(self, a, b, mod): # 快速计算(a*b) % mod
ans = 0
while b:
if b & 1: # 判断当前位是否为1
ans = (ans + a) % mod # ans+=a
b >>= 1 # b向前移位
a = (a + a) % mod # 更新a
return ans
def q_pow(self, a, b, mod): # 快速计算(a^b) % mod
ans = 1
while b:
if b & 1:
ans = self.q_mul(ans, a, mod) # ans*=a
b >>= 1
a = self.q_mul(a, a, mod)
return ans
def cutRope(self , n: int) -> int:
if n <= 3:
return n -1
if n % 3 == 0:
return self.q_pow(3, n // 3, self.mod)
if n % 3 == 1:
return self.q_mul(self.q_pow(3, n // 3 -1, self.mod), 4, self.mod)
else:
return self.q_mul(self.q_pow(3, n // 3, self.mod), 2, self.mod)
class Solution: def cutRope(self , number: int) -> int: # write code here if number<=3: return number-1 # res=1 if number%3==1: n=number//3-1 res=self.new_pow(3,n)*4 elif number%3==0: n=number//3 res=self.new_pow(3,n) else: n=number//3 res=self.new_pow(3,n)*2 return res%998244353 def new_pow(self,a,n): #快速幂函数 if n==0: return 1 if n%2==1: return self.new_pow(a, n-1)*a%998244353 else: temp=self.new_pow(a, n//2)%998244353 return temp*temp%998244353
class Solution: def cutRope(self, number: int) -> int: # 尽可能切割出3 if number == 2: return 1 if number == 3: return 2 if number % 3 == 1: return self.pow(number// 3-1) * 4%998244353 if number % 3 == 2: return self.pow(number// 3) * 2%998244353 else: return self.pow(number // 3)%998244353 def pow(self, n, base=3): # 快速幂 if n==0: return 1 if n % 2 == 0: mul = self.pow(n //2) return mul * mul%998244353 else: return base * self.pow(n - 1) %998244353放一个Python3的递归快速幂。
public class ShengZi { public static void main(String[] args) { System.out.println(cutRope(7)); } public static long cutRope(long number) { // write code here long result = 0; if (number <= 3) { result = number - 1; } else { long x = number % 3; if (x == 0) { result = calculatePower(3, (long) (number / 3)); } if (x == 1) { result = 4 * calculatePower(3, (long) (number / 3 - 1)); } if (x == 2) { result = 2 * calculatePower(3, (long) (number / 3)) ; } } return result% 998244353; } public static long calculatePower(long num, long power) { long sum = 1; while (power > 0) { if (power % 2 > 0) { sum = (sum * num) % 998244353; } num = num * num % 998244353; power = power / 2; } return sum; } }