首页 > 其他分享 >对CF1904C的代码优化

对CF1904C的代码优化

时间:2024-01-21 19:11:09浏览次数:40  
标签:begin 下标 int CF1904C value 代码优化 ans 指针

https://www.luogu.com.cn/problem/CF1904C

分讨,然后 \(k = 2\) 的时候肯定要写暴力,但是我的暴力很不优雅。

石山

void solve() {
    int n, k;
    cin >> n >> k;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    if (k >= 3) {
        cout << 0 << endl;
        return ;
    }
    sort(a.begin() + 1, a.begin() + n + 1);
    ll ans = a[1];
    if (k == 1) {
        for (int i = 2; i <= n; i++) {
            ans = min(ans, a[i] - a[i - 1]);
        }
        cout << ans << endl;
    }
    else {
        for (int i = 2; i <= n; i++) {
            ans = min(ans, a[i] - a[i - 1]);
        }
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                ll value = a[j] - a[i];
                auto right_it = lower_bound(a.begin() + 1, a.begin() + n + 1, value);
                if (right_it == a.begin() + n + 1) {
                    ans = min(ans, abs(a[n] - value));
                }
                if (*right_it == value) {
                    cout << 0 << endl;
                    return ;
                }
                else if (right_it == a.begin() + 1){
                    ans = min(ans, abs(value - *right_it));
                }
                else {
                    auto left_it = prev(right_it);
                    ans = min(ans, min(abs(value - *right_it), abs(value - *left_it)));
                }
            }
        }
        cout << ans << endl;
    }
}

代码运用了大量指针操作,各种特判,难以阅读,debug。

指的一提的是,我一开始又把 lower_bound 记成找 val 大于等于的第一个数组中的元素,后面想起来是找数组中第一个大于等于 val 的元素。影响到了其中一个迭代器的特判,改完才过。

过是过了,代码仍然是依托史。

优化

  • 先从最简单的复用性来看。

    for (int i = 2; i <= n; i++) {
    	ans = min(ans, a[i] - a[i - 1]);
    }
    

    这段代码是找第一轮时的最小值,无论 \(k = 1\) 还是 \(k = 2\) 都是需要的,但我却在两个 if 中写了两遍。

    直接把代码块提到 if 外。

  • 再从思路上优化。

    for (int i = 1; i <= n; i++) {
    	for (int j = i + 1; j <= n; j++) {
    		ll value = a[j] - a[i];
    		auto right_it = lower_bound(a.begin() + 1, a.begin() + n + 1, value);
    		if (right_it == a.begin() + n + 1) {
    			ans = min(ans, abs(a[n] - value));
    		}
    		if (*right_it == value) {
                cout << 0 << endl;
                return ;
         	}
            else if (right_it == a.begin() + 1){
             	ans = min(ans, abs(value - *right_it));
            }
          	else {
          		auto left_it = prev(right_it);
        		ans = min(ans, min(abs(value - *right_it), abs(value - *left_it)));
          	}
     	}
    }
    
    • 这一大坨特判,主要是我对于指针操作的ptsd。

      • 比如第一个特判,我如果不加上,直接用第二个,如果第二个指针指向 end ,那就会出错。
    • 一种行之有效的优化方式,不用指针。

      • lower_bound 返回的指针减去 a.begin() + 1 ,先转化为下标,之后都用下标角度考虑。

        这里注意,减去首指针之后,一定要加一,因为这个计算的是该元素到首指针的下标差,而我要求的是下标(我的下标从一开始)

        int p = lower_bound(a.begin() + 1, a.begin() + n + 1, value) - (a.begin() + 1) + 1;
        
      • 对于第一个 if,因为哪怕 lb 找不到大于等于 val 的元素,返回 a.begin() + n + 1 减去之后也是得到 \(n\),正符合了我第一个特判用的 \(a_n - value\)。

        if (right_it == a.begin() + n + 1) {
        	ans = min(ans, abs(a[n] - value));
        }
        

        这段代码等价于

        ans = min(ans, a[p] - value);
        
      • 对于后面几个 if 无非是找与 value 左右相邻两个的元素找最小的解,然后其中一个 if 判断如果在最左边,就不能找最左边的。用指针的话,左边还要用到 prev,而下标直接简单相减就行。

        if (p <= n) ans = min(ans, a[p] - value);
        if (p >= 1) ans = min(ans, value - a[p - 1]);
        

    优雅

    void solve() {
        int n, k;
        cin >> n >> k;
        vector<ll> a(n + 1);
        for (int i = 1; i <= n; i++) cin >> a[i];
        if (k >= 3) {
            cout << 0 << endl;
            return ;
        }
        sort(a.begin() + 1, a.begin() + n + 1);
        ll ans = a[1];
        for (int i = 2; i <= n; i++) {
            ans = min(ans, a[i] - a[i - 1]);
        }
        if (k == 1) {
            cout << ans << endl;
            return ;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                ll value = a[j] - a[i];
                int p = lower_bound(a.begin() + 1, a.begin() + n + 1, value) - (a.begin() + 1) + 1;
                if (p <= n) ans = min(ans, abs(a[p] - value));
                if (p >= 2) ans = min(ans, abs(value - a[p - 1]));
            }
        }
        cout << ans << endl;
    }
    

标签:begin,下标,int,CF1904C,value,代码优化,ans,指针
From: https://www.cnblogs.com/kdlyh/p/17978185

相关文章

  • 使用 Swift 代码优化项目编译速度
    引言软件的性能是评价一个软件质量的重要指标,尤其在今天这个时代,性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件,如网银系统、在线购物商城等,更是必须保证其高效稳定的性能。在这种背景下,优化项目的编译速度就显得尤为重要。本文将介绍如何使用Swift代码优化......
  • 代码优化
    1.搭建minio2.修改后端文件上传接口  在用户添加service中将avatar的值设置为修改上传接口 3.修改不能修改用户名 在添加用户的index.vue中添加账户绑定disable默认值为false,用来控制修改的不能修改用户名   4.上传文件优化把img的地址改为form.avatar......
  • django代码优化全局变量定义
    django代码优化全局变量定义需要根据不同年级的学生肺活量进行分数获取,在根据分数*权重得到最终分数。不同年级权重不同旧代码定义####肺活量,权重0.15calculate_lung_100=100*0.15calculate_lung_95=95*0.15calculate_lung_90=90*0.15calculate_lung_85=8......
  • 嵌入式代码优化技巧
    内存管理技巧1.C/C++工程应尽量避免深拷贝,尽量用浅拷贝(指针或者引用),如果指针需要频繁拷贝,用智能指针是一种不错的选择2.启用内存池管理线程的内存开销,事先在堆里边分配好,然后快速使用避免复杂的浮点运算1.复杂的浮点运算尽量避免,有些芯片是不支持硬件双精度浮点数的,比如全志T3,......
  • Go代码优化
    1、Go语言的if语句允许在条件之前传递一个语句。原始代码:f,contains:=factory[string(token)]ifcontains{//Dosomething}优化:(稍微提高了代码的可读性)iff,contains:=factory[sToken];contains{//Dosomething} ......
  • 如何l利用`ThreadLocal`、`HandlerInterceptor`、`HandlerMethodArgumentResolver`来
    核心类ThreadLocal、HandlerInterceptor、HandlerMethodArgumentResolver1.ThreadLocal2.WebMvcConfigurer -addArgumentResolvers3.HandlerMethodArgumentResolver -supportsParameter -resolveArgumentThreadLocal:可以理解为一个线程安全的Map。//用户上下......
  • 小程序性能提速秘籍:CSS代码优化,让小程序轻松翻倍酷炫!
    引言:Hello,小程序开发小能手们!是不是有时候发现小程序的加载速度有点慢,页面样式显示有点乱?别急,今天小编要传授一招“CSS代码优化”的技能,让你的小程序风驰电掣,页面秒变酷炫!我们要一起玩得开心,不让性能问题影响我们的小程序!......
  • 11 13vue代码优化
    今天基本学完了前端vue,整理vue:接口封装//定制请求的实例//导入axios npminstallaxiosimportaxiosfrom'axios';import{ElMessage}from'element-plus'//定义一个变量,记录公共的前缀 , baseURL//constbaseURL='http://localhost:8080';constbaseURL=......
  • 11 11 vue3代码优化
     使用axios发送异步请求是这种格式,现在异步请求都封装到api中。说法如下:接口调用的js代码一般都会封装到js文件中,并一函数的形式暴露给外部,例如: 这张图片包括了没有参数和有参数的两种情况 然后在组件中的script中调用函数就行,但这样不行,好像跟什么同步异步有关,反正这样......
  • Matlab代码优化之道
    ​ 一、遵守PerformanceAcceleration的规则关于什么是“PerformanceAcceleration”请参阅matlab的帮助文件。1、只有使用以下数据类型,matlab才会对其加速:logical,char,int8,uint8,int16,uint16,int32,uint32,double而语句中如果使用了非以上的数据类型则不会加速,如numeric......