浅谈常数优化

所谓常数优化,就是优化一些常数,使它们变得更小,常见的几种优化方式有更改输入输出方式,优化写法,位运算等途径进行各种操作使得程序更快

这里主要提一些高效的优化方式

读入优化

非众所周知,对于C++来说有三种常见的读入方式即: c i n s c s a n f r e a d (快读),这几种读入方式各有优点和缺点,这里简单提一下

c i n ,C++标准的读入方式,读入字符串有得天独厚的优势,适应性强,使用简单,方便,可以文件输入同步,缺点是速度十分慢
s c a n f ,适合格式化输入:擅长精度控制、隔行输入等十分方便,常用于处理一些数字中间掺和符号的读入,但处理字符串没有 c i n 方便,但速度比 c i n 快很多,功能复杂多样,是C++最常见的读入方式。
r e a d ,又称读入优化,其优化原理是基于C++ g e t c h a r 运算速度非常快,可以实现高效率读入大规模数据,且就有很强的伸缩性,可以在其函数内进行一些特判,例如跳过字母等等,缺点是对新手来说有点难理解,是中高阶选手普遍普遍使用的读入方式,缺点是输入单一,处理数据功能弱

代码片段

函数形式

int read()
{
    int d=1;//符号
    int f=0;//结果
    char c;//加速关键
    while(c=getchar(),c<=47||c>=58)/*在这里你可以加入一些判断,例如遇到负号将d赋值为-1,或者
    遇到换行标记等等*/
    f=(f<<3)+(f<<1)+c-48;//位运算加速,等下会在后面的位运算优化中提到
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;//保存数字
    return f*d;//这里乘d是处理负数专用
}

过程形式

void read(int &f)//因为我们需要把快读的结果返回给f,所以要加地址符&
{
    char c;int d=1;f=0;//下面的基本一致
    while(c=getchar(),c<=47||c>=58);
    f=(f<<3)+(f<<1)+c-48;//相当于f*10+c-48
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
    return;
}

究极优化版本

#define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++)
char BB[1<<15],*S=BB,*T=BB;;
IL LL read()
{
    f=0;Re char c; 
    while(c=getchar(),c<=47||c>=58);f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
    return f;
}

输出优化

非众所周知,C++也有三种常见的三种输出方式 c o u t , p r i n t f , w r i t e (输出流),这三种输出方式分别对应 c i n , p r i n t f , r e a d ,速度排序也基本一致

c o u t ,C++标准的输出方式,简单通俗易懂,使用方便,速度慢
p r i n t f ,格式化输出神奇,场宽,精度等操作统统适用,且可以在里面插加字符
w r i t e ,基于C++ p u t c h a r 输出神搜的输出算法,可以在 l o g 10 ( n ) 的时间内高速输出一个数字,且可以处理 _ _ i n t 128 ,缺点是输出范围狭小。

程序片段

基本程序

void write(int x)
{
    /*在这一行你可以进行一些特殊处理和判断,例如处理负数等*/
    if(x>9) write(x/10);//能分解则分解
    putchar(x%10+48);//利用C++putchar速度快的因素加速输出
}

改造输出优化,需搭配上面的进行
1.输出后空格

void writespace(int x)
{
    write(x);putchar(32);return;//这里仍然利用了puchar速度快的优点
}

2.输出后换行

void writeln(int x)
{
    write(x);putchar(10);//依旧利用putchar快速的优点,达到十分快速的效果
}

位运算优化

众所周知,所有的电脑信息处理都是基于二进制的,冯诺依曼先生提出的这个思想给我们又带来了优化的契机,在C++中,加减乘除等运算的运行效率实在不敢恭维,特别是mod运算更是慢的可怜,所以在很多时候,我们可以运用到位运算进行速度优化,具体做法这里就不多说了,就是尽量把代码中的运算多使用二进制进行,这会让你的代码运行飞快

指针优化

指针是一个十分强大的功能,其可以利用十分可观的空间实行超高的效率,指针的做法这里也不多说了,请读者自行阅读有关书籍吧。

诡异的优化

在所有的 i n t 前加上 r e g i s t e r ,在所有的 v o i d f u n c i t i o n 前加上 i n l i n e ,把主程序的 i n t 改成 s i g n e d 就可以达到一个十分诡异的速度!

非比赛允许优化

之所以把这个放在最后,是因为这些优化是NOIP系列竞赛所不允许使用的,但你在平常做题,编题的过程中也可以用到,但不建议多次使用,还是要靠自己努力的。
常见的这类优化有 o 2 , o 3 , o f a s t 优化,这里就放出比较基本的优化了

#pragma GCC optimize(2)//常数优化
#pragma once//保证头文件只被编译一次

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81021585