POJ 2109 Power of Cryptography【高精度+二分 Or double水过~~】
题目链接:
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水过~~】的更多相关文章
- POJ - 2109 Power of Cryptography(高精度log+二分)
Current work in cryptography involves (among other things) large prime numbers and computing powers ...
- POJ 2109 Power of Cryptography 大数,二分,泰勒定理 难度:2
import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger p,l,r,d ...
- 贪心 POJ 2109 Power of Cryptography
题目地址:http://poj.org/problem?id=2109 /* 题意:k ^ n = p,求k 1. double + pow:因为double装得下p,k = pow (p, 1 / ...
- POJ 2109 -- Power of Cryptography
Power of Cryptography Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 26622 Accepted: ...
- POJ 2109 Power of Cryptography 数学题 double和float精度和范围
Power of Cryptography Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21354 Accepted: 107 ...
- poj 2109 Power of Cryptography
点击打开链接 Power of Cryptography Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16388 Ac ...
- poj 2109 Power of Cryptography (double 精度)
题目:http://poj.org/problem?id=2109 题意:求一个整数k,使得k满足kn=p. 思路:exp()用来计算以e为底的x次方值,即ex值,然后将结果返回.log是自然对数,就 ...
- 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 ...
- POJ 2109 :Power of Cryptography
Power of Cryptography Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18258 Accepted: ...
随机推荐
- UVA 11971 Polygon 多边形(连续概率)
题意: 一根长度为n的木条,随机选k个位置将其切成k+1段,问这k+1段能组成k+1条边的多边形的概率? 思路: 数学题.要求的是概率,明显与n无关. 将木条围成一个圆后再开切k+1刀,得到k+1段. ...
- 洛谷 P2604 [ZJOI2010]网络扩容
题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. ...
- javaee 第四周作业
分析hello.java.下载链接:https://github.com/javaee/tutorial-examples/tree/master/web/jsf/hello1 /** * Copyr ...
- EEPROM的存储大小
学习单片机时,常见的EEPROM如24C02的大小为2Kbit(有的也称2KB).这里的2KB到底能存储多少数据呢? 2KB中,B表示单位bit,K表示1024. 单片机编程中常用的数据类型为unsi ...
- libs/tools.js stringToDate dateToString 日期字符串转换函数
libs/tools.js stringToDate dateToString 日期字符串转换函数 import { stringToDate } from '@/libs/tools.js' e ...
- 利用CWinThread实现跨线程父子MFC窗口
利用CWinThread实现跨线程父子MFC窗口 MFC对象只能由创建该对象的线程访问,而不能由其他线程访问. 不遵守该准则将导致断言(assertion)或者无法预知的程序行为等运行期错误. 在多线 ...
- Web前端技术体系大全搜索
一.前端技术框架 1.Vue.js 官网:https://cn.vuejs.org/ Vue CLI:https://cli.vuejs.org/ 菜鸟教程:http://www.runoob.com ...
- vscode 中文设置
修改设置 语言设置介绍: https://code.visualstudio.com/docs/getstarted/locales 按Ctrl + Shift + P打开命令调色板,然后开始键入“d ...
- Ztree 多选,显示勾选的路径
项目要求,需要向后台传递已经勾选的路径,如 l1-a, l1-l3-c,l1-l3-d;(如果是全选状态则只传递全选状态的路径,不传子节点). 具体可以参考jQ Ztree 的 v3.5 版本 Me ...
- mysql 删除恢复
一.模拟误删除数据表的恢复 1 二进制日志功能启用 vim /etc/my.cnf [mysqld] log-bin 2 完全备份 mysqldump -A -F --master-data=2 - ...