算法竞赛中的一系列时间优化技巧

  总所周知,在蓝桥杯,ACM,天梯赛,百度之星等一系列程序设计竞赛中都对程序运行时间有一定的限制。

  一个C++代码一秒运行大概在5e8次附近,所以针对题目给的数据范围就要想出不同的解法。

  这里盗用yxc总结的不同数据范围对应的算法内容

9a0c671a8589432eba337db9dbf5df56.png 

同时,除了时间优化火车头。还有一些其他的技巧。

1 快读快写

//字符串的快读快写

#include<bits/stdc++.h>
using namespace std;
inline string readstr() {
    string s = "";
    char ch;
    while ((ch = getchar()) != '\n') {
        s += ch;
    }
    return s;
}
inline void writestr(string s) {
    for (int i = 0; i < s.size(); i++) putchar(s[i]);
}
int main() {
    string s;
    cout << "输入:" << endl;
    s = readstr();
    cout << "输出:" << endl;
    writestr(s);
}
//浮点数的快读快写

#include<bits/stdc++.h>
using namespace std;
inline double readdou() { //inline内联函数进一步优化速度
    double x = 0; int flag = 0;//x是返回值,flag表示正负
    char ch = 0; //初始化为空格
    while (!isdigit(ch)) { //当输入不是数字时,一直读入但不记录到x中(建议直接使用isdigit判断)
        flag |= (ch == '-');
        ch = getchar();
    }
    while (isdigit(ch)) { //当输入的是数字时,一直记录到x中
        x = x * 10 + (ch - '0'); //double不能用位运算了
        ch = getchar();
    }
    if (ch != '.') return flag ? -x : x; //如果后面跟的不是小数点,则直接结束
    int f = 1; //f用于设置某数字所对应的值
    ch = getchar();
    while (isdigit(ch)) {
        x = x + (ch - '0') * pow(10, -f); //pow!
        f++; //乘10^-1表示小数点后的第一位的值,10^-2表示小数点后的第二位的值...
        ch = getchar();
    }
    return flag ? -x : x;
}
inline void write(int x) {
    char num[30]; //存放翻转后的数字,方便输出
    int cnt = 0; //num数组的大小
    if (x == 0) { putchar('0'); return; }
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    while (x > 0) { //将数字分解成字符
        num[cnt++] = x % 10 + '0';
        x /= 10;
    }
    while (cnt > 0) {
        putchar(num[--cnt]);
    }
}
inline void writedou(double x) {
    write(int(x)); //先输出x的整数部分
    //减去x的整数部分
    if (x < 0) x = -x;
    x -= int(x);
    if (x!=0) putchar('.');
    while (x) { //循环输出小数部分
        x *= 10;
        putchar(int(x) + '0');
        x -= int(x);
    }
}
int main() {
    double x;
    cout << "输入:" << endl;
    x = readdou();
    cout << "输出:" << endl;
    writedou(x);
    return 0;
}

//整数的快读与快写

#include<bits/stdc++.h>
using namespace std;
inline int read() { //inline内联函数进一步优化速度
    int x = 0, f = 0; //x是返回值,f表示正负
    char ch = 0; //初始化为空格
    while (!isdigit(ch)) { //当输入不是数字时,一直读入但不记录到x中(建议直接使用isdigit判断)
        f |= (ch == '-');
        ch = getchar();
    }
    while (isdigit(ch)) { //当输入的是数字时,一直记录到x中
        x = (x << 3) + (x << 1) + (ch ^ 48); //(x<<3)+(x<<1)->x*10  ch^48->ch-'0'
        ch = getchar();
    }
    return f? -x: x;
}
inline void write(int x) {
    char num[30]; //存放翻转后的数字,方便输出
    int cnt = 0; //num数组的大小
    if (x == 0) { putchar('0'); return; }
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    while (x > 0) { //将数字分解成字符
        num[cnt++] = x % 10 + '0';
        x /= 10;
    }
    while (cnt > 0) {
        putchar(num[--cnt]);
    }
}
int main() {
    int x;
    cout << "输入:" << endl;
    x = read();
    cout << "输出:" << endl;
    write(x);
    return 0;
}

2 关闭同步流 

ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

3 不使用endl 

          使用endl会强制刷新缓冲区,会消耗大量时间,可以用‘\n’代替。

4 总结

       优化算法时间复杂度还是要尽可能的从算法的构思入手,同时注意一些卡常的细枝末节。

 

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值