- 题目大意
求一个数k(0~ 109 )满足 kn=p ,1<=n<=200,1<=p<10^101 - 分析
被题目坑了,题目说k为整数,然而数据有分数的情况,调试了两三个小时还是没发现错(小数据的对拍做了也没问题),看到别人的题解才知道题目有问题。还好最后AC了,不然就要疯掉了。
就是对k的值进行二分,高精度算出k的n次方和p比较。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
char s[3000];
int n;
int p[3000];
void Change(char *s,int *x,int &len)
{
len=0;
for(int i=0;s[i]!='\0';i++)len++;
for(int i=len-1;i>=0;i--)x[len-i]=(int)s[i]-(int)'0';
}
void Mul(int *x1,int len1,int *x2,int len2,int *x,int &len)
/*
x1乘x2结果存到x里
*/
{
int a[3000],b[3000];
for(int i=0;i<=2999;i++){a[i]=0; b[i]=0;}
for(int i=1;i<=len1;i++)a[i]=x1[i];
for(int i=1;i<=len2;i++)b[i]=x2[i];
for(int i=1;i<=2999;i++)x[i]=0;
int s=0,g=0;
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2+1;j++)
{
s=a[i]*b[j]+g;
g=s/10;
x[i+j-1]=x[i+j-1]+s%10;
for(int k=1;k<(len1+len2+2);k++)
{
if(x[k]>9)
{
x[k+1]++;
x[k]=x[k]-10;
}
}
}
}
if(x[len1+len2+1]!=0){len=len1+len2+1;return ;}
else if(x[len1+len2]!=0){len=len1+len2;return;}
else {len=len1+len2-1;return;}
}
int Compare(int *x1,int len_x1,int *x2,int len_x2)
/*
x1比x2大返回1
小返回-1
相等返回0
*/
{
if(len_x1!=len_x2)return len_x1>len_x2 ? 1 : -1;
for(int i=len_x1;i>=1;i--)
{
if(x1[i]>x2[i])return 1;
if(x1[i]<x2[i])return -1;
}
return 0;
}
void Pow(int *x1,int lenth1,int m,int *x2,int &lenth2)
/*
x1的m次方,x数组从一开始到lenth下标结束
结果存在x2中
*/
{
int t[3000];int len=lenth1;
for(int i=1;i<=lenth1;i++)t[i]=x1[i];
if(m==0)
{
x2[1]=1;
lenth2=1;
return ;
}
if(m==1)
{
for(int i=1;i<=lenth1;i++)x2[i]=x1[i];
lenth2=lenth1;
return ;
}
if(m%2==0)
{
Pow(t,len,m/2,x2,lenth2);
Mul(x2,lenth2,x2,lenth2,x2,lenth2);
return;
}
if(m%2==1)
{
Pow(t,len,m/2,x2,lenth2);
Mul(x2,lenth2,x2,lenth2,x2,lenth2);
Mul(x2,lenth2,x1,lenth1,x2,lenth2);
return ;
}
}
void Into_array(int a,int *x,int &len)
/*
把数a放进数组x里
*/
{
len=0;
while(a>0)
{
x[++len]=a%10;
a=a/10;
}
}
int Find_k(int *p,int len_p)
{
int l=1;
int r=1000000000;
int tm;
while(l<r)
{
tm=(l+r)/2;
int m[3000];
int len_m;
Into_array(tm,m,len_m);
int t[3000];
int len_t=0;
Pow(m,len_m,n,t,len_t);
if(Compare(t,len_t,p,len_p)==1)r=tm;
else if(Compare(t,len_t,p,len_p)==-1)
{
if(r-l==1)return l;
else l=tm;
}
else return tm;
}
return l;
}
int main()
{
//freopen("in.txt","r",stdin); //从in.txt 中读入数据
// freopen("out.txt","w",stdout);
while(scanf("%d%s",&n,&s)!=EOF)
{
int len;
Change(s,p,len);
cout<<Find_k(p,len)<<endl;
}
//fclose(stdin);
// fclose(stdout);
}
- 这道题的trick
这道题不用高精度用double也能AC
#include<iostream>
#include<cmath>
using namespace std;
double n,p;
int main(){
while(cin>>n>>p){
cout<<pow(p,1/n)<<endl;
}
}
这巨大的落差让我想哭,就当练手感了吧。