【poj】1001
【题目】
Exponentiation
Time Limit: 500MS Memory Limit: 10000K
Total Submissions: 123707 Accepted: 30202
Description
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
Input
The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.
Output
The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.
Sample Input
95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
Hint
If you don't know how to determine wheather encounted the end of input:
s is a string and n is an integer
C++
while(cin>>s>>n)
{
...
}
c
while(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want
/*while(scanf(%s%d",s,&n)!=EOF) //this also work */
{
...
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
这道题是我真正意义上的第一道题。所以写的很乱。估计再过上一段时间后连自己都看不懂。
大概思路:因为没有任何一种数据类型能够容纳这种高精度运算的结果。所以用数组来储存数据。求幂的实质就是n-1次乘法运算。运算之前把对字符串进行处理(提取小数点,同时记录指数),转化为整形数组。值得注意的是,要在整形数组后面开始储存。比如储存1234,是a[MAX-1]=4;a[MAX-2]=3;..这样有助于乘法运算的时候向前进一位。运算过程结束后再转化为字符串。重新加入小数点。
这一题做了很久很久,走了不少弯路,也就收货了一些经验:
1.代码的书写很重要。最好能形成层层缩进的结构。这样美观大方修改起来十分方便。
2.在写代码之前最好能够先详细构思一下。也就是所谓的建模。不要一有idea就马上动笔写下来。这次我就是很快把核心部分写了下来,却因为没有一个完整的架构。修修补补花了大量的时间。
3.审题。一开始看错题目、、、、满满的都是泪啊。
4.测试的时候没有进行全面的考虑。后期引用了这位兄弟的测试数据才ac。http://www.cnblogs.com/lililqth/p/3187758.html
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAX 500
int pows(char [],char [],int ,int []); //高精度计算pow
char *deal(char [],int ,int ); //处理计算好的字符串。
int find(char []); //寻找小数点所在位置,
int cf(int [],int ,int [],int ); //高精度乘法
int main(){
char ins[MAX],des[MAX],*res;
int n,index,len=;
int temp[MAX];
while(scanf("%s%d",ins,&n)!=EOF)
{ index=find(ins);
memset(temp,,*MAX);
len=pows(ins,des,n,temp);
if(len!=)
{
res=deal(des,len,temp[MAX-]); //传递指数
des[MAX-]='\0'; //给倒数第二位加上字符串结束符
printf("%s\n",res);
}
else return ; }
}
int find(char des[MAX])
{
int i=,index=-;
for(i=;i<=strlen(des);i++)
if(des[i]=='.'){
index=i;
return index;}
return -; //默认没有找到小数点
}
char *deal(char des[],int len,int en){
int i,ts=,zhi=,k=;
//重新加入小数点
zhi=MAX--(-en); //小数点位置
if((-en)==len) { //-,小数点在刚好在第一位
des[zhi]='.';
return &des[zhi]; }
else if((-en)>len) { //二,数值小于1的情况,0.0xx;
for(i=zhi;i<MAX--len;i++)
des[i]='';
des[zhi]='.';
return &des[zhi]; }
else if(en==) //三,若此为整数,则直接返回字符串值
return &des[MAX--len];
else
{ //四,数值大于1的情况
for(i=MAX--len;i<=zhi;i++)
des[i-]=des[i]; //将小数点所在位置的前方往左挪一位。
des[zhi]='.';
return &des[MAX--len];
}
} int pows(char ins[MAX],char des[MAX],int n,int temp[MAX])
{
int t2[MAX]={};
int i=,index=-,k=,m=,ji=,h=,kj=;
int len=strlen(ins);
index=find(ins);
m=len;
if(n==)
{ //n=0
for(i=;i<=len-;i++)
if(ins[i]!=''){ //这个数不等于0
temp[MAX-]=;
temp[MAX-]=;
break; }
else return ; //不可以计算0的0次幂
}
else if(n==)
{ //n=1
for(i=;i<=len-;i++) //从第一个位置开始遍历,检查前面是否有无意义的零
if(ins[i]!='')
break;
if(i==len)
{ //整个字符串全为0
m=;
temp[MAX-]=; //表明这是一个整数
}
else
{ //前面有无意义的0,此处包含无0的情况
m=len-i-;
//复制小数点之后的
for(kj=MAX-,h=len-;h>index;h--,kj--)
temp[kj]=ins[h]-;
temp[MAX-]=-(len-index-); //记录指数
//复制小数点之前的
for(k=h-;k>=i;kj--,k--)
temp[kj]=ins[k]-;
}
for(i=len-,k=;i>=;i--) { //从后面开始扫描有没有无意义的0
if(ins[i]!='')
break;
k++; } //计算有多少个0
if(i<len-)
{ //后面有无意义的0
if(ins[i]=='.')
{ //1.00样式
m -=k;
for(h=MAX-;h>=MAX--m;h--)
temp[h]=temp[h-k];
temp[MAX-]=; //标记为整数
}
else
{ //1.**00的样式
m -=k;
for(h=MAX-;h>=MAX--m;h--)
temp[h]=temp[h-k];
temp[MAX-] +=k; //修改指数
}
}
}
else
{ //n>=2
if(index==-)
{ //一。整数,没有找到小数点
for(i=;i<=len-;i++) {
temp[MAX--len+i]=ins[i]-;
t2[MAX--len+i]=ins[i]-;
}
}
else
{ //二找到小数点
if(index==)
{ //处理形式为 。**的形式的实数
for(i=len;i>=;i--)
ins[i]=ins[i-];
ins[]='';
len++;
}
i=len-;
while(ins[i]=='') i--; //从最后一个字符开始检查,检查最后是否带有无意义的0
if(i<len-)
{ //******后面带有无意义的0 if(ins[i]=='.')
{ //-----1.00的形式
len=i; //连同小数点一起抛弃
index=-; //将该数标记为整数
for(i=;i<=len-;i++)
{ //复制到整形数组中
temp[MAX--len+i]=ins[i]-;
t2[MAX--len+i]=ins[i]-;
}
}
else
{ //------1.**000的形式
len=i+;
for(i=;i<=index-;i++) { //用两个for循环将字符串转换为整形数组,并且要将从右边开始写入
temp[MAX--len+i]=ins[i]-; //从整形数组的倒数第三位开始储存
t2[MAX--len+i]=ins[i]-; }
//跳过小数点
for(k=index+;k<=len-;k++,i++){
temp[MAX--len+i]=ins[k]-;
t2[MAX--len+i]=ins[k]-; }
}
}
else
{ //******后面没有无意义的0 for(i=;i<=index-;i++) { //用两个for循环将字符串转换为整形数组,并且要将从右边开始写入
temp[MAX--len+i]=ins[i]-; //从整形数组的倒数第三位开始储存
t2[MAX--len+i]=ins[i]-;} for(k=index+;k<=len-;k++,i++) { //跳过小数点
temp[MAX--len+i]=ins[k]-;
t2[MAX--len+i]=ins[k]-; }
}
}
//在数组的最后一位记录这两个数的指数
if(index==-)
{ //如果为整数则将该指数部分置为0
temp[MAX-]=;
t2[MAX-]=;
k=len;
m=len;
}
else
{ //不为整数
temp[MAX-]=index-len+;
t2[MAX-]=index-len+;
k=len-;
m=len-;
}
for(i=;i<n-;i++) //pow的核心
{ //需要n-1次乘法
cf(temp,m,t2,k); //cf返回temp数组中所含数的长度
for(ji=;ji<=MAX-;ji++)
{ //计算temp中的数的长度
if(temp[ji]!=){
m=MAX-ji-;
break; }
}
}
}
//重新将字符转换为数值
for(i=MAX-;i>=MAX--m+;i--) //从整形数组倒数第三位开始复制到字符串的倒数第三位
des[i]=temp[i]+;
return m; //返回字符串的长度
}
int cf(int temp[MAX],int m,int src[MAX],int k){
int t[MAX]={};
int i=,num=;
int sr=,tmp=MAX-,j=sr;
temp[MAX-]=; //防止k在边界时溢出.在倒数第二位储存0
src[MAX-]=;
// 用两个for循环来完成两个数的相乘
for(sr=MAX-;sr>=MAX-m-;sr--) //数组的倒数第三位储存数的最低位
{
for(tmp=MAX-,j=sr;tmp>=MAX--m;tmp--,j--) //src从个位开始每位乘以temp中的每一位 //之所以使j=sr--我们在计算两数相乘时总会将下一行的数向左挪一位。
t[j] +=src[sr]*temp[tmp];
}
//将t复制到temp中
for(i=MAX-;i>=sr-m+;i--)
temp[i]=t[i];
for(i=MAX-;i>=sr-m;i--)
{ // 处理temp中的数,过十进一,每一位只保留个位,需要注意的是有可能是进百位。故要把i提前到temp左端的前两格
temp[i] +=num;
num= (temp[i]-temp[i]%)/; //保存当前一位的十位数和百位数.如128保留12;
temp[i]=temp[i]%; //进位后,只保存个位数
}
temp[MAX-] +=src[MAX-]; //处理指数部分的相乘
return ;
}
【poj】1001的更多相关文章
- 【POJ】1704 Georgia and Bob(Staircase Nim)
Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...
- 【POJ】1067 取石子游戏(博弈论)
Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
- 【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉
DP/单调队列优化 首先不考虑奶牛的喜欢区间,dp方程当然是比较显然的:$ f[i]=min(f[k])+1,i-2*b \leq k \leq i-2*a $ 当然这里的$i$和$k$都是偶数啦~ ...
- 【POJ】【2104】区间第K大
可持久化线段树 可持久化线段树是一种神奇的数据结构,它跟我们原来常用的线段树不同,它每次更新是不更改原来数据的,而是新开节点,维护它的历史版本,实现“可持久化”.(当然视情况也会有需要修改的时候) 可 ...
- 【POJ】1222 EXTENDED LIGHTS OUT
[算法]高斯消元 [题解] 高斯消元经典题型:异或方程组 poj 1222 高斯消元详解 异或相当于相加后mod2 异或方程组就是把加减消元全部改为异或. 异或性质:00 11为假,01 10为真.与 ...
- 【POJ】2892 Tunnel Warfare
[算法]平衡树(treap) [题解]treap知识见数据结构 在POJ把语言从G++换成C++就过了……??? #include<cstdio> #include<algorith ...
- 【POJ】【1637】Sightseeing tour
网络流/最大流 愚人节快乐XD 这题是给一个混合图(既有有向边又有无向边),让你判断是否有欧拉回路…… 我们知道如果一个[连通]图中每个节点都满足[入度=出度]那么就一定有欧拉回路…… 那么每条边都可 ...
- 【POJ】3070 Fibonacci
[算法]矩阵快速幂 [题解] 根据f[n]=f[n-1]+f[n-2],可以构造递推矩阵: $$\begin{vmatrix}1 & 1\\ 1 & 0\end{vmatrix} \t ...
- 【POJ】3233 Matrix Power Series
[算法]二分+矩阵快速幂 [题意]给定矩阵A和整数k,MOD,求A^0+A^1+A^2+...+A^k. [题解] 定义题目要求的答案为f(n),即: $$f_n=\sum_{i=0}^{n}A^i$ ...
随机推荐
- 【hihoCoder第十五周】最近公共祖先·二
老实说我没有读题,看见标题直接就写了,毕竟hiho上面都是裸的算法演练. 大概看了下输入输出,套着bin神的模板,做了个正反map映射,但是怎么都得不了满分.等这周结束后,找高人询问下trick. 若 ...
- python在一个列表中查找
# -*- coding: utf-8 -*-__author__ = 'Administrator'import bisect#简化一些操作#1:在一个列表中查找""" ...
- android设备之间屏幕共享
近期公司在开发一款android的设备把屏幕投射到手机上.同一时候手机还能够触控.键盘操作.这样.就达到了屏幕共享的目的. 思考了一下.主要思路: 1.将截图所获取的位图用ffmpeg编码成视频流. ...
- 【Linux】linux经常使用基本命令
Linux中很多经常使用命令是必须掌握的,这里将我学linux入门时学的一些经常使用的基本命令分享给大家一下,希望能够帮助你们. 这个是我将鸟哥书上的进行了一下整理的,希望不要涉及到版权问题. 1.显 ...
- 关于SetCapture() 和 ReleaseCapture()的使用方法
查MSND,对SetCapture()函数的说明为:“该函数在属于当前线程的指定窗体里设置鼠标捕获.一旦窗体捕获了鼠标,全部鼠标输入都针对该窗体,不管光标是否在窗体的边界内.同一时刻仅仅能有一个窗体捕 ...
- WebSphere配置数据库连接池
通过WebSphere配置数据库连接池一共需要三项: 1.配置连接驱动,在这里叫:JDBC提供程序; 2.配置数据库连接池,在这里叫:配置数据源; 3.配置数据库登录帐号,密码,在这里 ...
- Android字数限制的EditText实现方案研究
在应用开发中,有时需要实现有字数限制的EditText,首先来分析下市面上存在的类似实现方案吧,好有个感性的认识. [方案一:腾讯微博] 每个中文字符算一个字数,每两个英文字符算一个字数,当用户输入内 ...
- [MVC4-基礎] 使用DataAnnotations+jQuery進行表單驗證
我目前有以下表單,Select部分因為必須上一層有選擇下層才有資料,因此使用jQuery驗證問題類型是否有選擇就好,而問題描述要驗證是否為空,這裡採用MVC內建的DataAnnotations來驗證. ...
- IE6,IE7下滚动条没有生效解决方法
需要加个相对定位 position:relative;
- avalon学习笔记一 列表及条件过滤
好长时间都没有更新博客了,不是因为没有学习新的东西,而是到了新的单位每天玩命加班实在是太累了!经过一年的努力吧,终于可以轻松一下了.废话少说,直接干货吧! 由于是学习阶段,就直接拿了公司的二级页面做了 ...