C++的各种优化

前言

  众所周知,有一些可(bian)爱(tai)的题单纯使用那些算法会T,所以需要用一些神奇的优化。

读入优化

  既用过pascal,又用过c++的选手们都可以感受到知道,c++虽然快,但它的读入scanf()慢得一匹,cin>>就更不必说了。所以,在输入数据≥ 10 6 的情况下,程序运行的时间基本上都在读入上了……
  所以,有没有可能让c++掌握pascal的read()呢?
  答案是肯定的。
  因为,pascal的read()之所以快,就在于它是一个一个字符读入,然后再转化为数字的;所以c++的读入优化就是手动实现pascal的read()。
  最基本的读入优化如下:

void read(int &x)
{
    char ch=getchar(); x=0;
    for(;ch<'0'||ch>'9';ch=getchar());
    for(;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
}

  当然,我们还可以装逼一点,使用下面这种打法:

#include<cctype>
void read(int &x)
{
    char ch=getchar(); x=0;
    for(;!isdigit(ch);ch=getchar());
    for(;isdigit(ch);x=(x<<3)+(x<<1)+(ch^48),ch=getchar());
}

  isdigit(x)判断x是否是0~9的整数 。
  注意要用cctype头文件。
  
  但是,如果你要读入int、long long这些不同的数据类型,又嫌打两个读入优化冗长的话,可以使用下面的神奇做法:

template<class T>void read(T &x)
{
    x=0;int f=0;char ch=getchar();//f表示正负性,所以这个可以读入负数
    while(!isdigit(ch))  {f|=(ch=='-');ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return;
}

  其中,template是定义模板的方法。我们可以用它来定义一个函数模板,譬如上面的代码。
  这样一来,我们可以使用它读入int、long long等类型,它就会自动把T替换成int、long long。

  读入实数就复杂一点,要判断小数点。

输出优化

  在个别输出巨多的题中,使用输出优化也可以优化很多。
  下面是用递归实现的输出优化:

inline void write(int x)
{
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0');
}

-O2

  -O2和下面要说的-O3都是比赛时不能用的(毕竟要考虑到pascal选手的心情),不过平常可以用一用,娱乐娱乐。用法主要下面两项:

  1. 被卡常,悠哉悠哉地贴个-O2就过了;
  2. 打暴力,加个-O2,可以梦想多骗点分。
    目前我看到的-O2有两种开法,第一种放在程序开头:
    #pragma GCC optimize(2)
      第二种放在每个函数(包括主函数)前面:
    __attribute__((optimize("-O2")))
      据说它内部的实现是打开了很多个优化开关(当然具体原理我也不懂),所以就能让你的程序起飞。

-O3

  -O3是-O2的升级版,所以大部分时间它能优化得更快。不过它不大稳定,有时比-O2慢好多,有时甚至开了跟没开一样。
  亦是放在每个函数前面:
__attribute__((optimize("-O3")))

猜你喜欢

转载自blog.csdn.net/qq_36551189/article/details/80086471