题目链接:

http://poj.org/problem?id=2109

参考:

http://blog.csdn.net/code_pang/article/details/8263971

题意:

给定n,p,求k使得kn=p(1≤n≤200, 1≤p<10101, 1≤k≤109)

分析:

高精度+二分~~

k的位数为p的位数除以n的向上取整,这样知道k的位数便可以在范围内二分了~注意这里的答案是向下取整~~

代码:

#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
#define MAXN 9999
#define MAXSIZE 1000
#define DLEN 4
const int maxn = 205;
char p[maxn];
class BigNum
{
private:
int a[500];
int len;
public:
BigNum(){
len = 1;
memset(a, 0 ,sizeof(a));
}
BigNum(const int);
BigNum(const char*);
BigNum(const BigNum &);
BigNum &operator = (const BigNum &); BigNum operator +(const BigNum &)const ;
BigNum operator*(const BigNum &)const ;
BigNum operator^(const int &)const ;
bool operator >(const int &)const;
bool operator >(const BigNum &T)const; void print();
};
BigNum::BigNum(const int b)
{
int c, d = b;
len = 0;
while(d > MAXN){
c = d % (MAXN + 1);
d = d / (MAXN + 1);
a[len++] = c;
}
a[len++] = d;
}
BigNum::BigNum(const char*s)
{
int t, k, index;
memset(a,0,sizeof(a));
int l = strlen(s);
len = l / DLEN;
if(l % DLEN)
len++;
index=0;
for(int i = l - 1; i >= 0; i -= DLEN){
t = 0;
k = i - DLEN + 1;
if(k<0) k=0;
for(int j = k; j <= i; j++)
t = t * 10 + s[j] - '0';
a[index++] = t;
}
}
BigNum::BigNum(const BigNum & T) : len(T.len)
{
memset(a, 0, sizeof(a));
for(int i = 0 ; i < len ; i++)
a[i] = T.a[i];
}
BigNum & BigNum::operator=(const BigNum & n)
{
len = n.len;
memset(a, 0, sizeof(a));
for(int i = 0 ; i < len ; i++)
a[i] = n.a[i];
return *this;
}
BigNum BigNum::operator+(const BigNum & T) const
{
BigNum t(*this);
int big; //位数
big = T.len > len ? T.len : len;
for(int i = 0; i < big; i++){
t.a[i] +=T.a[i];
if(t.a[i] > MAXN){
t.a[i + 1]++;
t.a[i] -=MAXN+1;
}
}
if(t.a[big] != 0) t.len = big + 1;
else t.len = big;
return t;
}
BigNum BigNum::operator*(const BigNum & T) const
{
BigNum ret;
int up;
int temp,temp1;
int i, j;
for(i = 0 ; i < len ; i++){
up = 0;
for(j = 0 ; j < T.len ; j++){
temp = a[i] * T.a[j] + ret.a[i + j] + up;
if(temp > MAXN){
temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
up = temp / (MAXN + 1);
ret.a[i + j] = temp1;
}
else{
up = 0;
ret.a[i + j] = temp;
}
}
if(up != 0)
ret.a[i + j] = up;
}
ret.len = i + j;
while(ret.a[ret.len - 1] == 0 && ret.len > 1)
ret.len--;
return ret;
}
BigNum BigNum::operator^(const int & n) const
{
BigNum t,ret(1);
if(n < 0) exit(-1);
if(n == 0) return 1;
if(n == 1) return *this;
int m = n;
int i;
while(m > 1){
t = *this;
for(i = 1; i<<1<=m; i <<= 1)
t = t * t;
m -= i;
ret = ret * t;
if(m == 1) ret=ret*(*this);
}
return ret;
}
bool BigNum::operator>(const BigNum & T) const
{
int ln;
if(len > T.len)
return true;
else if(len == T.len){
ln = len - 1;
while(a[ln] == T.a[ln] && ln >= 0)
ln--;
if(ln >= 0 && a[ln] > T.a[ln])
return true;
else
return false;
}
else
return false;
}
bool BigNum::operator >(const int & t) const
{
BigNum b(t);
return *this>b;
}
void BigNum::print()
{
printf("%d",a[len-1]);
for(int i = len - 2 ; i >= 0 ; i--) printf("%04d",a[i]);
printf("\n");
}
int main(void)
{
int n, len, MIN, MAX, MID;
while(~scanf("%d%s", &n, &p)){
len = (int)ceil((double)strlen(p) / n);
MIN = 1, MAX = 9;
for(int i = 0; i < len - 1; i++){
MAX *= 10;
MAX += 9;
MIN *= 10;
}
while(MIN < MAX){//[]
MID = (MIN + MAX) / 2;
if(BigNum(p) > (BigNum(MID) ^ n)) MIN = MID +1;
else if((BigNum(MID) ^ n) > BigNum(p)) MAX = MID - 1;
else break;
}
if(MAX == MIN) MID = MIN;
if((BigNum(MID) ^ n) > BigNum(p)) MID--;
printf("%d\n",MID);
}
return 0;
}

代码:

double类型能表示10−307到10308, 足够这个题用。

而double超过16位后面都变成0,这样正好满足向下取整。

12337=4332529576639313702577

12347=4357186184021382204544

12357=4381962969567270546875

值不同的地方(从高到低第三位)没有超过double的精度,所以不会导致错误答案~

#include<iostream>
#include<cmath>
using namespace std;
int main (void)
{
double n, m;
while(cin>>n>>m){
cout<<pow(m, 1/n)<<endl;
}
return 0;
} //或者 #include<iostream>
#include<cmath>
using namespace std;
int main (void)
{
double n, p;
while(cin>>n>>p){
cout<< exp(log(p)/n) <<endl;
}
return 0;
}
//pow明显更快,只是想说明有时候取对数也是个不错的方法~

POJ 2109 Power of Cryptography【高精度+二分 Or double水过~~】的更多相关文章

  1. POJ - 2109 Power of Cryptography(高精度log+二分)

    Current work in cryptography involves (among other things) large prime numbers and computing powers ...

  2. POJ 2109 Power of Cryptography 大数,二分,泰勒定理 难度:2

    import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger p,l,r,d ...

  3. 贪心 POJ 2109 Power of Cryptography

    题目地址:http://poj.org/problem?id=2109 /* 题意:k ^ n = p,求k 1. double + pow:因为double装得下p,k = pow (p, 1 / ...

  4. POJ 2109 -- Power of Cryptography

    Power of Cryptography Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26622   Accepted: ...

  5. POJ 2109 Power of Cryptography 数学题 double和float精度和范围

    Power of Cryptography Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21354 Accepted: 107 ...

  6. poj 2109 Power of Cryptography

    点击打开链接 Power of Cryptography Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16388   Ac ...

  7. poj 2109 Power of Cryptography (double 精度)

    题目:http://poj.org/problem?id=2109 题意:求一个整数k,使得k满足kn=p. 思路:exp()用来计算以e为底的x次方值,即ex值,然后将结果返回.log是自然对数,就 ...

  8. Poj 2109 / OpenJudge 2109 Power of Cryptography

    1.Link: http://poj.org/problem?id=2109 http://bailian.openjudge.cn/practice/2109/ 2.Content: Power o ...

  9. POJ 2109 :Power of Cryptography

    Power of Cryptography Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18258   Accepted: ...

随机推荐

  1. The Performance Manifesto

    Manifesto For Performance Testing And Engineering We choose to support others in their quest for bet ...

  2. IOS之UIStepper控件详解

    在iOS5中新增了一个数字输入控件UIStepper,它可以递进式输入数量.UIStepper继承自UIControl,它主要的事件是UIControlEventValueChanged,每当它的值改 ...

  3. 通过HA方式操作HDFS

    之前操作hdfs的时候,都是固定namenode的地址,然后去操作.这个时候就必须判断namenode的状态为active还是standby,比较繁琐,如果集群使用了HA的形式,就很方便了 直接上代码 ...

  4. 使用windows的fsutil命令创建指定大小及类型的测试文件

    在软件测试中,对于上传.下载一类功能常常需要用不同大小的文件进行测试. 使用Windows命令fsutil可以生成任意大小.任意类型文件. C:\Users\axia\fsutil file crea ...

  5. codevs 2761 脏话过滤

    时间限制: 1 s  空间限制: 8000 KB  题目等级 : 白银 Silver   题目描述 Description 某论坛希望打造文明论坛,对于每个帖子需要将脏话换成*输出. 脏话有38,25 ...

  6. Python——集合与字典练习

    集合与字典练习question1问题描述:有一个列表,其中包括 10 个元素,例如这个列表是[1,2,3,4,5,6,7,8,9,0],要求将列表中的每个元素一次向前移动一个位置,第一个元素到列表的最 ...

  7. 0xc000007b——应用程序无法正常启动

    0xc000007b——应用程序无法正常启动 原因:缺少exe程序启动所需要的DLL.

  8. QT_8_Qt中的事件处理_定时器事件_定时器类_事件分发器_事件过滤器_绘图事件_高级绘图事件_绘图设备_QFile 文件读写_QFileInfo文件信息

    Qt中的事件处理 1.1. 捕获QLabel中是鼠标事件 1.2. enterevent 鼠标进入 1.3. leaveevent 鼠标离开 1.4. 鼠标按下MyLabel::mousePressE ...

  9. 【转载】WampServer图标显示红色后变成橙色怎么解决

    WampServer就是Windows Apache Mysql PHP集成安装环境,即在window下的apache.php和mysql的服务器软件. 工具/原料   WampServer 方法/步 ...

  10. ubuntu14.04 configure: error: xml2-config not found. Please check your libxml2 installation错误解决

    今天在ubuntu14.04上安装php7时 执行:./configure命令时 一直报configure: error: xml2-config not found. Please check yo ...