#include <iostream>
#include <algorithm>
using namespace std;
//计算大数加法
string bigAdd(string s1, string s2) {
int s1Size = s1.size();
int s2Size = s2.size();
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
string res = "";
int carrier = 0;
if (s1Size > s2Size) {
for (int i = 0; i < s2Size; i++) {
int bitsum = (s1.at(i) - '0') + (s2.at(i) - '0') + carrier;
if (bitsum >= 10) {
bitsum -= 10;
carrier = 1;
} else {
carrier = 0;
}
res += to_string(bitsum);
}
for (int i = s2Size; i < s1Size; i++) {
int bitsum = (s1.at(i) - '0') + carrier;
if (bitsum >= 10) {
bitsum -= 10;
carrier = 1;
} else {
carrier = 0;
}
res += to_string(bitsum);
}
if (carrier == 1) {
res += "1";
}
} else if (s1Size == s2Size) {
for (int i = 0; i < s1Size; i++) {
int bitsum = (s1.at(i) - '0') + (s2.at(i) - '0') + carrier;
if (bitsum >= 10) {
bitsum -= 10;
carrier = 1;
} else {
carrier = 0;
}
res += to_string(bitsum);
}
if (carrier == 1) {
res += "1";
}
} else {
for (int i = 0; i < s1Size; i++) {
int bitsum = (s1.at(i) - '0') + (s2.at(i) - '0') + carrier;
if (bitsum >= 10) {
bitsum -= 10;
carrier = 1;
} else {
carrier = 0;
}
res += to_string(bitsum);
}
for (int i = s1Size; i < s2Size; i++) {
int bitsum = (s2.at(i) - '0') + carrier;
if (bitsum >= 10) {
bitsum -= 10;
carrier = 1;
} else {
carrier = 0;
}
res += to_string(bitsum);
}
if (carrier == 1) {
res += "1";
}
}
reverse(res.begin(), res.end());
return res;
}
//计算大数乘法
string bigMulti(string basenum, int a) {
string res = "0";
string zerostr = "";
reverse(basenum.begin(), basenum.end());
while (a > 0) {
int tmpa = a % 10;
string tmpres="";
int carrier = 0;
for (int i = 0; i < basenum.size(); i++) {
int multinum = (basenum.at(i) - '0') * tmpa + carrier;
if (multinum >= 10) {
carrier = multinum / 10;
multinum = multinum % 10;
} else {
carrier = 0;
}
tmpres += to_string(multinum);
}
if (carrier != 0) {
tmpres += to_string(carrier);
}
tmpres=zerostr+tmpres;
reverse(tmpres.begin(), tmpres.end());
res=bigAdd(tmpres,res);
a=a/10;
zerostr += "0";
}
return res;
}
//计算大数除法 s1/s2
string bigDivide(string s1, string s2) {
int lastnum=0;
string res="";
bool isExact=false;
bool firstnozero=false;
for(int i=0;i<s1.size();i++){
int nownum=(s1.at(i)-'0')+lastnum;
if(nownum/stoi(s2)==0){
lastnum=nownum*10;
if(firstnozero){
res+="0";
}
}else{
if(!firstnozero){
firstnozero=true;
}
int nowbit=nownum/stoi(s2);
res+=to_string(nowbit);
lastnum=(nownum%stoi(s2))*10;
}
if(i==(s1.size()-1)){
if(lastnum==0){
isExact=true;
}else{
res="-1";//表示没有除尽
}
}
}
return res;
}
int main() {
int n, a;
while (cin >> n >> a) { // 注意 while 处理多个 case
int kcounter = 0;
string nown = "1";
//注意这个地方要到n+1,因为写到n的时候还只是计算的(n-1)!
for (int i = 1; i <= n+1; i++) {
string nowdivires=bigDivide(nown, to_string(a));
if (nowdivires!= "-1") {
nown = nowdivires;
kcounter++;
nown = bigMulti(nowdivires, i);
} else {
nown = bigMulti(nown, i);
}
}
cout<<kcounter<<endl;
}
}
// 64 位输出请用 printf("%lld")
这可能是效率最低最笨的方式了,模拟了阶乘的计算,主要思想是:
1、使用大整数的加减乘除方法
2、在计算阶乘结果res1过程中对被除数a^k进行除法运算,如果能整除就把k++,res1变成除完以后的数,这样当完成阶乘运算时,得到的也是k的最大值



京公网安备 11010502036488号