[acm 1001] c++ 大数加法 乘法 幂
北大的ACM 1001
代码纯手动编写 - -
#include <iostream>
#include <cstdio>
#include <cstring> class BigNumber
{
struct BigNumberNode
{
BigNumberNode():n(0), prev(NULL), next(NULL){}
BigNumberNode(int N):n(N), prev(NULL), next(NULL){} int n;
BigNumberNode *prev, *next;
}; BigNumberNode *head, *tail;
int dot_before; // 小数点之前的数量
int dot_later; // 小数点之后的数量 void InsertNodeAtBegin(int n)
{
BigNumberNode *new_node = new BigNumberNode(n);
if(head != NULL)
{
head->prev = new_node;
new_node->prev = NULL;
new_node->next = head;
head = new_node;
}
else
{
head = new_node;
tail = new_node;
new_node->prev = NULL;
new_node->next = NULL;
}
} void InsetNodeAtEnd(int n)
{
BigNumberNode *new_node = new BigNumberNode(n);
if(head != NULL)
{
new_node->prev = tail;
new_node->next = NULL;
tail->next = new_node;
tail = new_node;
}
else
{
head = new_node;
tail = new_node;
new_node->prev = NULL;
new_node->next = NULL;
}
} void DeleteBegin()
{
if(head != NULL)
{
if (head->next != NULL)
{
BigNumberNode* temp = head->next;
delete head;
head = temp;
temp->prev = NULL; if (dot_before != 0)
{
dot_before--;
}
else
{
dot_later--;
}
}
else
{
Free();
}
}
} void DeleteEnd()
{
if(tail != NULL)
{
if (tail->prev != NULL)
{
BigNumberNode* temp = tail->prev;
delete tail;
tail = temp;
temp->next = NULL; if (dot_later != 0)
{
dot_later--;
}
else
{
dot_before--;
}
}
else
{
Free();
}
}
} // 去除前/后导 0
// 去除前/后导 0
void ClearZeros()
{
// 后导 0
BigNumberNode *p; int max_limit = dot_later;
for(int i = 0; i < max_limit; i++)
{
p = tail; if(p->n == 0)
{
DeleteEnd();
}
else
{
break;
}
} // 前导 0
max_limit = dot_before;
for(int i = 0; i < max_limit; i++)
{
p = head; if(p->n == 0)
{
DeleteBegin();
}
else
{
break;
}
}
} BigNumber Mul(const BigNumber &Scale)
{
const BigNumber &a = *this, &b = Scale;
BigNumber sum_big_number; int sum = 0;
int reserve = 0;
int tag = 0; BigNumberNode *pa = a.tail, *pb = b.tail; // xxxxxx a
// xxx b
// --------- Mul
// xxxxxx
// xxxxxx
// xxxxxx
// --------- Add
// xxxxxxxxx while(pb)
{
BigNumber temp_big_number;
pa = a.tail;
while(pa)
{
sum = pa->n * pb->n + reserve;
reserve = sum / 10;
temp_big_number.InsertNodeAtBegin(sum - reserve * 10);
temp_big_number.dot_before++;
pa = pa->prev;
} if (reserve)
{
temp_big_number.InsertNodeAtBegin(reserve);
temp_big_number.dot_before++;
reserve = 0;
} for (int i = 0; i < tag; i++)
{
temp_big_number.InsetNodeAtEnd(0);
temp_big_number.dot_before++;
} sum_big_number += temp_big_number; tag++;
pb = pb->prev;
} sum_big_number.dot_later = a.dot_later + b.dot_later; if (sum_big_number.dot_before > sum_big_number.dot_later)
{
sum_big_number.dot_before -= sum_big_number.dot_later;
}
else
{
int temp = sum_big_number.dot_later - sum_big_number.dot_before;
sum_big_number.dot_before = 0;
for (int i = 0; i < temp; i++)
{
sum_big_number.InsertNodeAtBegin(0);
}
} sum_big_number.ClearZeros(); return sum_big_number;
} public: ~BigNumber()
{
Free();
} BigNumber(): head(NULL), tail(NULL), dot_before(0), dot_later(0)
{
} BigNumber(const char *Str): head(NULL), tail(NULL), dot_before(0), dot_later(0)
{
Free();
AdaptFormString(Str);
} BigNumber(const BigNumber& Source): head(NULL), tail(NULL), dot_before(0), dot_later(0)
{
*this = Source;
} const BigNumber& operator=(const BigNumber& Source)
{
if (this != &Source)
{
this->Free(); BigNumberNode *p = Source.head;
while(p)
{
this->InsetNodeAtEnd(p->n);
p = p->next;
} this->dot_before = Source.dot_before;
this->dot_later = Source.dot_later;
} return *this;
} BigNumber operator+(const BigNumber Addend)
{
const BigNumber &a = *this, &b = Addend;
BigNumber new_number; BigNumberNode *pa, *pb;
int sum, remain, odd;
int reserve = 0;
bool is_dot_before_longer_is_a; // 帮助标记小数点之前的部分
bool is_dot_later_longer_is_a; // 小数点之后
if(a.dot_later > b.dot_later)
{
pa = a.tail;
pb = b.tail;
remain = b.dot_later;
odd = a.dot_later - b.dot_later;
is_dot_later_longer_is_a = true;
}
else
{
pa = b.tail;
pb = a.tail;
remain = a.dot_later;
odd = b.dot_later - a.dot_later;
is_dot_later_longer_is_a = false;
} for (int i = 0; i < odd; i++)
{
new_number.InsertNodeAtBegin(pa->n);
new_number.dot_later++;
pa = pa->prev;
} for (int i = 0; i < remain; i++)
{
sum = pa->n + pb->n + reserve;
reserve = sum / 10;
new_number.InsertNodeAtBegin(sum - reserve * 10);
new_number.dot_later++;
pa = pa->prev;
pb = pb->prev;
} // 小数点之前
if(a.dot_before > b.dot_before)
{
remain = b.dot_before;
odd = a.dot_before - b.dot_before;
is_dot_before_longer_is_a = true;
}
else
{
remain = a.dot_before;
odd = b.dot_before - a.dot_before;
is_dot_before_longer_is_a = false;
} BigNumberNode *temp; // 用于交换 pa pb
if (is_dot_before_longer_is_a && is_dot_later_longer_is_a
|| !is_dot_before_longer_is_a && !is_dot_later_longer_is_a)
{
// 不用交换
}
else
{
temp = pa;
pa = pb;
pb = temp;
} for (int i = 0; i < remain; i++)
{
sum = pa->n + pb->n + reserve;
reserve = sum / 10;
new_number.InsertNodeAtBegin(sum - reserve * 10);
new_number.dot_before++;
pa = pa->prev;
pb = pb->prev;
} for (int i = 0; i < odd; i++)
{
sum = pa->n + reserve;
reserve = sum / 10;
new_number.InsertNodeAtBegin(sum - reserve * 10);
new_number.dot_before++;
pa = pa->prev;
} // 检测是否最后还有一位
if (reserve)
{
new_number.InsertNodeAtBegin(reserve);
new_number.dot_before++;
reserve = 0;
} new_number.ClearZeros(); return new_number;
} BigNumber operator*(const BigNumber& Scale)
{
return Mul(Scale);
} BigNumber& operator+=(const BigNumber Addend)
{
BigNumber &a = *this;
const BigNumber &b = Addend; BigNumberNode *pa = a.tail, *pb = b.tail;
int sum = 0, remain = 0, odd = 0;
int reserve = 0; // 小数点之后
if(a.dot_later > b.dot_later)
{
remain = b.dot_later;
odd = a.dot_later - b.dot_later; for (int i = 0; i < odd; i++)
{
pa = pa->prev;
}
}
else
{
remain = a.dot_later;
odd = b.dot_later - a.dot_later; char *odd_n = new char[odd];
for (int i = 1; i <= odd; i++)
{
odd_n[odd - i] = pb->n;
pb = pb->prev;
} for (int i = 0; i < odd; i++)
{
a.InsetNodeAtEnd(odd_n[i]);
a.dot_later++;
}
delete odd_n;
} for (int i = 0; i < remain; i++)
{
sum = pa->n + pb->n + reserve;
reserve = sum / 10;
pa->n = sum - reserve * 10; pa = pa->prev;
pb = pb->prev;
} // 小数点之前
if(a.dot_before > b.dot_before)
{
remain = b.dot_before;
odd = a.dot_before - b.dot_before; for (int i = 0; i < remain; i++)
{
sum = pa->n + pb->n + reserve;
reserve = sum / 10;
pa->n = sum - reserve * 10; pa = pa->prev;
pb = pb->prev;
} for (int i = 0; i < odd; i++)
{
sum = pa->n + reserve;
reserve = sum / 10;
pa->n = sum - reserve * 10; pa = pa->prev;
}
}
else
{
remain = a.dot_before;
odd = b.dot_before - a.dot_before; for (int i = 0; i < remain; i++)
{
sum = pa->n + pb->n + reserve;
reserve = sum / 10;
pa->n = sum - reserve * 10; pa = pa->prev;
pb = pb->prev;
} for (int i = 0; i < odd; i++)
{
sum = pb->n + reserve;
reserve = sum / 10;
a.InsertNodeAtBegin(sum - reserve * 10);
a.dot_before++;
pb = pb->prev;
} } // 检测是否最后还有一位
if (reserve)
{
a.InsertNodeAtBegin(reserve);
a.dot_before++;
} a.ClearZeros(); return *this;
} void _Print()
{
if(dot_before == 0 && dot_later == 0)
{
putchar('0');
}
else if (dot_later == 0)
{
BigNumberNode *p = head; while(p)
{
putchar(p->n + '0');
p = p->next;
}
}
else
{
BigNumberNode *p = head; for(int i = 0; i < dot_before; i++)
{
putchar(p->n + '0');
p = p->next;
} putchar('.'); while(p)
{
putchar(p->n + '0');
p = p->next;
}
}
} void PrintString()
{
if(dot_before == 0 && dot_later == 0)
{
putchar('0');
}
else if (dot_later == 0)
{
char *temp = new char[dot_before + dot_later + 2], *ptemp = temp;
BigNumberNode *p = head; while(p)
{
*ptemp = p->n + '0';
ptemp++;
p = p->next;
}
*ptemp = 0; std::cout<<temp<<'\n';
delete[] temp;
}
else
{
char *temp = new char[dot_before + dot_later + 2], *ptemp = temp;
BigNumberNode *p = head; for(int i = 0; i < dot_before; i++)
{
*ptemp = p->n + '0';
ptemp++;
p = p->next;
} *ptemp = '.';
ptemp++; while(p)
{
*ptemp = p->n + '0';
ptemp++;
p = p->next;
}
*ptemp = 0; std::cout<<temp<<'\n';
delete[] temp;
}
} void Free()
{
BigNumberNode *p = head, *temp; while(p)
{
temp = p;
p = p->next;
delete temp;
} head = NULL;
tail = NULL;
dot_before = 0;
dot_later = 0;
} // 从字符串建立数据,未加入错误检测
void AdaptFormString(const char *Str)
{
Free(); const char *pc = Str; // 小数点之前
while(*pc)
{
if(*pc != '.') // 0 ~ 9
{
InsetNodeAtEnd(*pc - '0');
dot_before++;
pc++;
}
else // 小数点之后
{
pc++;
while(*pc)
{
InsetNodeAtEnd(*pc - '0');
dot_later++;
pc++;
}
break;
}
} ClearZeros();
} }; // 自顶向下的动态规划
BigNumber* BigNumberPowUP(BigNumber* result[], int pow)
{
if( result[pow] )
{
return result[pow];
}
else
{
int left = pow / 2;
int right = pow - left; result[left] = BigNumberPowUP(result, left);
result[right] = BigNumberPowUP(result, right); result[pow] = new BigNumber((*result[left]) * (*result[right])); return result[pow];
}
} BigNumber BigNumberPow(const BigNumber& R, int pow)
{
BigNumber *result[26] = {0}; result[1] = new BigNumber(R); BigNumberPowUP(result, pow); BigNumber Result = *result[pow]; for (int i = 0; i <= pow; i++)
{
delete result[i];
} return Result;
} int main(void)
{
char Rstr[10];
int n; while(scanf("%s%d", Rstr, &n) != EOF)
{
BigNumber result = BigNumberPow(Rstr, n);
result.PrintString();
} return 0;
}
[acm 1001] c++ 大数加法 乘法 幂的更多相关文章
- vector、string实现大数加法乘法
理解 vector 是一个容器,是一个数据集,里边装了很多个元素.与数组最大的不同是 vector 可以动态增长. 用 vector 实现大数运算的关键是,以 string 的方式读入一个大数,然后将 ...
- sdut2613(This is an A+B Problem)大数加法(乘法)
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>u ...
- java实现大数加法、乘法(BigDecimal)
之前写过用vector.string实现大数加法,现在用java的BigDecimal类,代码简单很多.但是在online-judge上,java的代码运行时间和内存大得多. java大数加法:求a+ ...
- Hat's Fibonacci(大数加法+直接暴力)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1250 hdu1250: Hat's Fibonacci Time Limit: 2000/1000 M ...
- 玲珑杯1007-A 八进制大数加法(实现逻辑陷阱与题目套路)
题目连接:http://www.ifrog.cc/acm/problem/1056 DESCRIPTION Two octal number integers a, b are given, and ...
- 【大数加法】POJ-1503、NYOJ-103
1503:Integer Inquiry 总时间限制: 1000ms 内存限制: 65536kB 描述 One of the first users of BIT's new supercompu ...
- NI笔试——大数加法
NI笔试: 1.找出字符串第一次出现的字符.用数组建立哈希表,然后再扫描字符串并判断次数是否为1. 2.大数加法,即字符串加法.因为之前写过乘法,就以为是乘法.然后就把乘法写上去了····= = 好了 ...
- A + B Problem II(大数加法)
http://acm.hdu.edu.cn/showproblem.php?pid=1002 A + B Problem II Time Limit: 2000/1000 MS (Java/Other ...
- 大数加法~HDU 1002 A + B Problem II
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1002 题意: 数学题,A+B; 思路,这个数非常大,普通加法一定会超时,所以用大数加法.大数加法的基 ...
随机推荐
- OPPO R7在哪里打开USB调试模式的详细流程
在我们使用PC连接安卓手机的时候,如果手机没有开启USB调试模式,PC则没办法成功检测到我们的手机,这时我们需要想办法将手机的USB调试模式打开,如下资料我们介绍OPPO R7如何开启USB调试模式的 ...
- Python的html解析器
转自https://blog.csdn.net/jqh2002_blog/article/details/24842217 其实比较不同的解析器对html的处理能力是有点麻烦的,因为它们处理的步骤并不 ...
- 如何为 Vue 项目写单元测试
https://www.w3ctech.com/topic/2052 如何为 Vue 项目写单元测试 前端工程 明非 2017-07-18 4685 访问 1 分享 微信分享 译者:明非 链接:htt ...
- 存储器的保护(二)——《x86汇编语言:从实模式到保护模式》读书笔记19
接着上一篇博文说. 5.代码段执行时的保护 每个代码段都有自己的段界限.同栈段一个道理,有效界限和G位相关. G=0:有效界限 = 描述符中的段界限 G=1:有效界限 = 描述符中的段界限值 * 0x ...
- JAVA源码之JDK(二)——Integer、Long、Double
这篇文章继续java.lang包下的源码学习,笔者也是找了几个比较常用的来阅读.下面针对Integer.Long.Double这样的基本类型的封装类,记录一些比较经典.常用的方法的学习心得,如toSt ...
- 万物智联,腾讯云 IoT 边缘计算揭秘——云+未来峰会开发者专场回顾
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:现在是万物互联的时代,智能穿戴设备,智能家居,无人商业,改变了我们的生活方式.预计到2021年,全球物联网设数将达到150亿,超过手机 ...
- Hibernate 一对一映射(惟一外键)
- bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划
Description 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的 ...
- Laravel 使用Voyager导致多个数据库连接总是返回默认连接?
问题与分析 最近的项目碰到一个奇怪的问题,在Laravel(5.3)中想建立多个数据库连接连到MySQL的不同数据库(另一个连接名为conn2),执行如下语句得到却发现得到的仍然是默认连接: $con ...
- android 9 patch