给你一根长度为 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
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
请问大佬为什么最后一例通不过啊,先取出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 { 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; } }
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; } }