题目链接:

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. laravel关联用户

    参考文档:模型关联-反向关联 belongsToor 模型层 app/Post.php public function user() { return $this->belongsTo('\Ap ...

  2. ssm框架搭建(下) 简单案例

    前言 这段时间没有更新博客,一直想做一个基于ssm的简单的项目.经过多次的尝试,终于实现了简单的增删查改功能了. 正文 由于前端的技术不是很熟悉,经过多方的查阅,使用了bootstrap的样式,来使界 ...

  3. 洛谷 P2053 [SCOI2007]修车

    题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待 ...

  4. 【转载】SQL Server 2012 日志传送

    SQL Server 2012 日志传送 一.准备: 数据库为完全恢复模式,并事先做一次完全备份. 共享一个文件夹,主机备份放在这个文件夹,而且客户机有权访问这个共享文件夹. 二.基本配置 1.启动配 ...

  5. Git搭建自己的网站服务器(Linux)

    git服务器弄了半天终于搞定了,还是记录下吧,不然下次有得忘了 流程: 服务器 构建git目录 git用户,git组作为仓库管理 ssh授权(远程无需密码接入) hook(post-receive)自 ...

  6. liunx中安装软件的几种方式

    服务器安装包一般有四种方式 1.源代码包安装 自由度高  需要预编译,安装速度慢    2.rpm包手动安装   安装的缺点是文件的关联性太大 3. 二进制tar.gz格式 直接解压即可 如tomca ...

  7. core 中使用 nlog

    引包 代码 public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory logFac) ...

  8. index 定义 v-for 未使用变量 实际是没有 :key="index"

    需要有 :key="index" <Checkbox :label="item.key" :key="index" v-for=&qu ...

  9. 批处理 更新 svn git hg

    @echo off Setlocal enabledelayedexpansion ::CODER BY Administrator POWERD BY iBAT 1.6 ::设置svn默认安装位置以 ...

  10. 448. Find All Numbers Disappeared in an Array@python

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...