题目大意:密码学的力量(是这个意思吧)
当前的密码学中包括(除了别的之外)large prime (大素数??)和 计算的数字在这些素数之间。在这一领域工作的结果在实际运用的结果从数论的结果和数学的其他分支曾被认为是唯一的理论兴趣。(好吧,还是不知道这句话是什么意思,略晕。)这个问题涉及到整数根的高效计算。
给你一个整数n, n >= 1, 并且一个整数p, p>=1,你需要写一个程序确定p的第n个整数根。这个问题中,给你一些整数n和p,p将永远是k到第n的形式(真心不理解啊!!!),对于一个整数k(这个整数是你的程序必须找到什么。)
输入包含两个整数n和p, 1<=n<=200, 1<=p<=10^101,并且存在一个整数k, 1 <= k <= 10^9 例如 k^n = p;
////////////////////////////////////////////题目的形容很是晦涩难懂,不过实际上只要最后一句就OK了,就是求那个K,坑啊。可以很明显看出来应该是一个大数,没有明天为啥是贪心,要求原来的数是多少,貌似要不断求开方,怎么开啊????
好吧,暂时没有什么好的思路,先放着!!
2014/12/02 16:03
有点想法了,可以用二分逼近找K,用快速幂求结果对10^9取余,只匹配最后几位,嘎嘎,不知道会不会对呢???试试吧
仔细一想取余貌似不行,不过又发现n不是太大,所以直接求吧
2014/12/02 17:00
竟然1A,好激动啊,嘎嘎
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define INF 1000000000
#define maxn 1005
long long a[maxn], b[maxn], bn;
int compaer(int A, int B);//返回0相等,返回负数这个数的B次方小于s,否则大于返回正数
void Pow(int A, int B);
int main()
{
char s[maxn];
int B;
while(scanf("%d%s", &B, s) != EOF)
{
int Start = 1, End = INF, Mid;
for(bn=0; s[bn]; bn++)
b[bn] = s[bn] - '0';
while(Start <= End)
{
Mid = (Start + End) / 2;
int k = compaer(Mid, B);
if(k == 0)break;
if(k < 0)
Start = Mid + 1;
else
End = Mid - 1;
}
printf("%d ", Mid);
}
return 0;
}
int compaer(int A, int B)//返回0相等,返回负数这个数的B次方小于s,否则大于返回正数
{
int k = B * log10(A) + 1;
if(k != bn)
return k - bn;
Pow(A, B);
for(int i=0; i<bn; i++)
{
if(a[i] != b[i])
return a[i] - b[i];
}
return 0;
}
void Pow(int A, int B)
{
int i, j, k=0, c[maxn] = {1};
for(i=0; i<B; i++)
{
for(j=0; j<=k; j++)
c[j] *= A;
for(j=0; j<=k; j++)
{
c[j+1] += c[j] / 10;
c[j] %= 10;
if(c[k+1])k++;
}
}
for(i=0; i<bn; i++)
a[i] = c[k--];
#include<stdlib.h>
#include<math.h>
#define INF 1000000000
#define maxn 1005
long long a[maxn], b[maxn], bn;
int compaer(int A, int B);//返回0相等,返回负数这个数的B次方小于s,否则大于返回正数
void Pow(int A, int B);
int main()
{
char s[maxn];
int B;
while(scanf("%d%s", &B, s) != EOF)
{
int Start = 1, End = INF, Mid;
for(bn=0; s[bn]; bn++)
b[bn] = s[bn] - '0';
while(Start <= End)
{
Mid = (Start + End) / 2;
int k = compaer(Mid, B);
if(k == 0)break;
if(k < 0)
Start = Mid + 1;
else
End = Mid - 1;
}
printf("%d ", Mid);
}
return 0;
}
int compaer(int A, int B)//返回0相等,返回负数这个数的B次方小于s,否则大于返回正数
{
int k = B * log10(A) + 1;
if(k != bn)
return k - bn;
Pow(A, B);
for(int i=0; i<bn; i++)
{
if(a[i] != b[i])
return a[i] - b[i];
}
return 0;
}
void Pow(int A, int B)
{
int i, j, k=0, c[maxn] = {1};
for(i=0; i<B; i++)
{
for(j=0; j<=k; j++)
c[j] *= A;
for(j=0; j<=k; j++)
{
c[j+1] += c[j] / 10;
c[j] %= 10;
if(c[k+1])k++;
}
}
for(i=0; i<bn; i++)
a[i] = c[k--];
}