ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AcWing 1248. 灵能传输 蓝桥杯

2022-03-29 18:31:40  阅读:204  来源: 互联网

标签:灵能 s0 蓝桥 传输 sn 数组 1248 AcWing


蓝桥杯的一道题:灵能传输 https://www.acwing.com/problem/content/description/1250/
首先是简化操作,将原数组转化为前缀和数组(下标都是从1开始),一次灵能传输对原数组涉及三个数(a[i-1],a[i],a[i+1])的操作,而且操作比较麻烦,但是如果转化成前缀和数组后等价于(s[i-1]与s[i])交换位置。

原来的目标是求a[i]绝对值最小值,那么现在的目标变为求s[i]-s[i-1]的绝对值最大值,其中设计的数有s[0~n]

2.由于对数组可以任意交换位置,经过简单的思考可以得知如果序列单调(后面就说成单增了),那么即为所求,那么对s数组排序即可。

但是存在一个问题,即s[0],s[n]参与最后求s[i]-s[i-1]的绝对值最大值的计算,但是由于题意可知s[0],s[n]是无法移动的,因此在此情况下怎么排序呢?

上面两种方式(这里假设s0 是小于sn的(如果是大于,swap一下就是一样的))

右边更优秀,为何?

简单理解就是由于s0比sn更小,因此左边s0到最大值比右边sn到最大值明显差值会小一些。

现在问题变为如何排成右边这种序列?

答案以代码呈现:

if(s0 > sn) swap(s0, sn);

        sort(s, s + n + 1);

        for(int i = 0; i <= n; i ++ )
            if(s[i] == s0) 
            {
                s0 = i;
                break;
            }

        for(int i = n; i >= 0; i -- )
            if(s[i] == sn)
            {
                sn = i;
                break;
            }

        memset(st, 0,sizeof st);
        int l = 0 ,r = n;

        for(int i = s0; i >= 0; i -= 2)
        {
            a[l ++ ] = s[i];
            st[i] = true;
        }

        for(int i = sn; i <= n; i += 2)
        {
            a[r -- ] = s[i];
            st[i] = true;
        }

        for(int i = 0; i <= n; i ++ )
            if(!st[i]) a[l ++ ] = s[i];


        LL res = 0;

        for(int i = 1; i <= n; i ++ ) res = max(res, abs(a[i] - a[i - 1]));

核心就是隔一个一取。

详细分析见:

标签:灵能,s0,蓝桥,传输,sn,数组,1248,AcWing
来源: https://www.cnblogs.com/swx123/p/16073261.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有