思路:二分法+大整数乘法
已知n,p,求k^n=p中的k。
知道n,p,则k的位数可以确定。假设为k为4位,则从1000至9999用二分查找逼近k,试探一个数的n次幂时用大整数乘法来做,直到得到那个k。
#include<iostream>
#include<cmath>
using namespace std;
char p[110];
int res[110] = { 0 }, resTemp[110] = {0};
int n, k_digits=0,p_digits=0;
void mutiply(int *a, int *b)
{
int i, j;
for (i = 0; i < 110; i++)
{
for (j = 0; j < 10; j++)
{
res[i+j] += a[i] * b[j];
}
}
for (i = 0; i < 110; i++)
{
res[i + 1] += res[i] / 10;
res[i] = res[i] % 10;
}
}
int func(int mid, int n)
{
int i=0;
int k[10] = { 0 }, temp[110] = {0};
//change mid->k from int to int*
while (mid!=0)
{
k[i] = mid % 10;
temp[i] = k[i];
mid = mid / 10;
i++;
}
//mutiply k n times
while ((n-1) != 0)
{
mutiply(temp,k);
for (i = 0; i < 110; i++)
{
temp[i] = res[i];
res[i] = 0;
}
n--;
}
//reverse p
for (i = 0; i < 110; i++)
{
resTemp[i] = 0;
}
for (i = p_digits-1 ; i>=0; i--)
{
resTemp[p_digits - i-1] = p[i]-'0';
}
//compare temp and resTemp
bool flag = false;
for (i = 110-1; i >=0 ; i--)
{
if (resTemp[i]>temp[i])
{
flag = true;
return -1;
}
else if (resTemp[i] < temp[i])
{
flag = true;
return 1;
}
}
if (flag == false)
{
return 0;
}
}
int main()
{
// k^n=p
int i,mid,min,max;
bool finish = false;
while (cin >> n >> p)
{
finish = false;
//identify the k's digits
for (i = 0; i < 110 && p[i] != '\0'; i++)
;
p_digits = i;
k_digits = (int)ceil((double)i / n);
for (i = 1, min = 1, max = 9; i < k_digits; i++)
{
min *= 10;
max *= 10;
max += 9;
}
//binary search k
while (!finish)
{
mid = (min + max) / 2;
if (min > max)
{
break;
}
int ans = func(mid,n);
switch (ans)
{
case -1:
min = mid + 1;
break;
case 0:
finish = true;
break;
case 1:
max = mid - 1;
break;
}//end switch
}//end binary search
cout << mid << endl;
}
return 0;
}