day05:枚举&模拟&高精度(了解原理,实现高精加)&文件重定向

目录

day05:枚举&模拟&高精度(了解原理,实现高精加)&文件重定向

枚举,其实就是穷举,把所有答案都遍历一遍,看是否满足要求

模拟:这个怎么说呢?其实就是让你干什么,你就干什么,按照它的要求来就是了。

对于枚举和模拟的题目主要是通过练题,提升自己的代码量来巩固,没有太多的知识点。

高精度
一个十分经典的问题:输入a b,求a+b的和
普通的话我们直接cout<<a+b就可以了,但是如果告诉你:

a,b是两个有100位长度的数据呢?这明显就不行了啊!
即使unsigned long long 的最大值也不过2^64=1.8e19

这就需要使用高精算法了,一般这类算法考的比较少,但是这样有趣的知识点,我们还是学习一下吧!

算法介绍

  a = 11111111
  b = 22222222
a+b = 33333333

  a = 8888,8888
  b = 9999,9999
a+b = 17 17 17 17, 17 17 17 17 (每位对应求和)
    = 17 17 17 17, 17 17 18  7 (开始进位)
    = 17 17 17 17, 17 18  8  7 (继续进位)
    = 17 17 17 17, 18  8  8  7 (继续进位)
    = 17 17 17 18,  8  8  8  7 (继续进位)
    = 17 17 17 18,  8  8  8  7 (继续进位)
    = 17 17 18  8,  8  8  8  7 (继续进位)
    = 17 18  8  8,  8  8  8  7 (继续进位)
    = 18  8  8  8,  8  8  8  7 (继续进位)
  = 1, 8  8  8  8,  8  8  8  7 (进位结束)

这就是高精度加法的原理,但是我们发现每次进位都是从后向前,
于是可以直接将数据翻转过来处理,最后输出或返回时在逆序即可。

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

//注意开全局变量,如果是局部变量很容易出现问题
const int MAXN=10005;
int A[MAXN],B[MAXN],C[MAXN], Ans[MAXN],Len_A,Len_B,Len_Ans;

void Read(int A[],int &Len) {
    string cur;    cin>>cur;
    Len=cur.length();
    for(int i=0; i<Len; i++) A[i] = cur[i]-'0';
    reverse(A,A+Len);//对A[0]..A[Len]进行翻转
}
int main() {
    Read(A,Len_A);    Read(B,Len_B);
    Len_Ans=max(Len_A,Len_B);
    for(int i=0; i<=Len_Ans; i++) {
        Ans[i]=A[i]+B[i]+C[i];    //加上前一位的进位值
        if(Ans[i]>9) C[i+1]=Ans[i]/10, Ans[i]-=10;//处理进位值
    }
    while(Ans[Len_Ans]>0) Len_Ans++; //位数是否增加
    for(int i=Len_Ans-1; i>=0; i--)    cout<<Ans[i];//输出结果 
    return 0;
}//该高精加模板源自CCF教材

高精加减乘的实现原理是大同小异的,高精除法需要转化使用减法的方式比较麻烦,但是很少考到这个,建议就是如果有时间可以将高精加减乘按照自己的风格写一遍。

另外注意一点:部分同学喜欢将计算结果返回为string类型,当然笔者也喜欢这样!
可是在string使用是会用到str.append()的用法,而这样的用法是在C11版本才有的,如果不支持C11那么这样的写法是不能AC的,比如:提交奥赛一本通的网站就会出bug

文件重定向
这个其实主要对于数据测试和竞赛中有用,平常用不上,但是比赛又必须要使用

freopen("输入文件名", "r", stdin); //替代我们的手动输入,将文件中内容读入输入流中
freopen("输出文件名", "w", stdout);//将输出流中的数据写入文件中

其实用这个来代替我们的手动输入是比较方便的,大家可以多习惯这样的用法。

举例:

普及组

(请选手务必仔细阅读本页内容)

一、题目概况

中文题目名称 a+b
英文题目与子目录名 ab
提交源程序文件名 ab.cpp
可执行文件名 ab.exe
输入文件名 ab.in
输出文件名 ab.out
每个测试点时限 1秒
测试点数目 10
每个测试点分 10
附加样例文件
结果比较方式 全文比较(过滤行末空格及文末回车)
题目类型 传统
运行内存上限 256MB
编译命令 g++ -o test test.cpp -lm
测试时长 10分钟

二、注意事项:
1、文件名(程序名和输入输出文件名)必须使用英文小写。
2、C/C++中函数 main()的返回值类型必须是 int,程序正常结束时的返回值必须是0。
3、全国统一评测时采用的机器配置为:CPU AMD Athlon(tm) Ⅱx2 240 process 2.8GHZ, 内存 4G,上述时限以此配置为准。
4、只提供 Linux 格式附加样例文件。
5、提交的程序代码文件的放置位置请参照各省的具体要求。
6、特别提醒:评测在当前最新公布的 NOI Linux 下进行,各语言的编译器版本以其为准。

【题目描述】输入a,b, 输出a+b的结果(0<=a+b<=2^31)。

#include<iostream>
using namespace std;
int main() {
    freopen("ab.in", "r", stdin);
    freopen("ab.out", "w", stdout);

    int a,b; cin>>a>>b;
    cout<<a+b;
    return 0;
}

这样程序就会从文件 ab.in 里面读取前两个数据,分别赋值给a,b,从而替代我们手动输入的过程。并且会将a+b的结果保存到文件 ab.out 里面,就不会在控制台窗口输出(也就是小黑方框)。

另外注意一点:题目一般会告诉你,我要提交什么样的源文件,比如 ab.cpp

上一篇:立方数差


下一篇:【LeetCode】1201.丑数III(python)