【招商银行2020FinTech研发赛道】写了一个简易的题解

自己写了一个简易的题解,不知道是不是正解,大家可以一起来讨论😉

A 金币

经典的数塔问题,自底向上走,可以避免边界条件处理,且结果容易得到

#include <bits/stdc++.h>

using namespace std;

int mmap[1030][1030], dp[1030][1030];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= i; ++j)
            scanf("%d", &mmap[i][j]);
    for(int i = 1; i <= n; ++i)
        dp[n][i] = mmap[n][i];
    for(int i = n - 1; i >= 1; --i)
        for(int j = 1; j <= i; ++j)
            dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + mmap[i][j];
    printf("%d\n", dp[1][1]);
    return 0;
}

B 交换座位

遍历,每次处理一对,如果不符合要求就需要进行交换,可以开一个值到下标的映射数组mmap来找到需要的值的位置,维护数组row和mmap即可

#include <bits/stdc++.h>

using namespace std;

int mmap[1030][1030], dp[1030][1030];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= i; ++j)
            scanf("%d", &mmap[i][j]);
    for(int i = 1; i <= n; ++i)
        dp[n][i] = mmap[n][i];
    for(int i = n - 1; i >= 1; --i)
        for(int j = 1; j <= i; ++j)
            dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + mmap[i][j];
    printf("%d\n", dp[1][1]);
    return 0;
}

C 修塔游戏

  • 由于要操作最高和最低,首先进行排序
  • k个相同的数必然出现在原数组中,那么可以枚举每一个数
  • 对于每一个数要操作后变成k个数,可以只操作左边,只操作右边,或者两边都进行操作,操作次数可以用前缀和简化计算得到,三种情况取最小即可
  • 注意到由于每次只能操作最高和最低的塔,可以观察到对于每一个数,操作完成后数组中的元素都会达到相等状态且都比目标值小1,比如 1 2 3 5,对于5,可以如下操作:1 2 3 5 -> 2 2 3 5 -> 2 3 3 5 -> 3 3 3 5 -> 3 3 4 5 -> 3 4 4 5 -> 4 4 4 5,这样如果最终相等的数多于k个,就需要减去多余的元素个数
  • 此外,还可以针对已经有k个相同的数进行特判
#include <bits/stdc++.h>

#define ll long long

using namespace std;

ll a[200005], presum[200005], cnt[10005];

int main()
{
    ll n, k;
    scanf("%lld %lld", &n, &k);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%lld", &a[i]);
        ++cnt[a[i]];
        if(cnt[a[i]] >= k)
        {
            printf("0\n");
            return 0;
        }
    }
    sort(a + 1, a + 1 + n);
    for(int i = 1; i <= n; ++i)
        presum[i] = presum[i-1] + a[i];
    ll ans = 0x3f3f3f3f3f3f3f3f;
    for(int i = 1; i <= n; ++i)
    {
        // 左边
        if(i >= k)
            ans = min(ans, i * a[i] - presum[i] - (i - k));
        // 右边
        if(n - i + 1 >= k)
            ans = min(ans, (presum[n] - presum[i-1]) - (n - i + 1) * a[i] - (n - i + 1 - k));
        // 两边一起
        ans = min(ans, i * a[i] - presum[i] + (presum[n] - presum[i-1]) - (n - i + 1) * a[i] - (n - k));
    }
    printf("%lld\n", ans);
    return 0;
}
全部评论

相关推荐

#暑期实习##招商银行#java:1.&nbsp;首先问了一下项目&nbsp;(黑马的外卖)2.&nbsp;多线程(线程池怎么工作的,讲了为什么需要线程池,以及各个参数的作用)3.&nbsp;你提到Excutor可能因为线程数过多或者等待队列太长而出现OOM,OOM发生在JVM的哪一块内存空间?&nbsp;(回答:堆),追问具体在堆的哪一块区域满了才会报OOM&nbsp;(回答:老年区)4.&nbsp;项目中SpringBoot的事务是怎么实现的(回答:启动类Enable事务然后在方法上加@Transction注解)5.&nbsp;SpringBoot的事务什么情况下会失效&nbsp;(回答:1.&nbsp;方法不是public的时候,&nbsp;2.&nbsp;异常必须要catch&nbsp;)mysql:1.&nbsp;了解索引吗,说一下对索引的理解2.&nbsp;什么情况下索引会失效或者说效果不好&nbsp;3.&nbsp;mysql事务隔离级别&nbsp;(说了一下四种分别是什么,分别有什么问题,怎么实现的)4.&nbsp;一般推荐使用哪一种&nbsp;(说使用默认的可重复读)redis:1.&nbsp;redis主从和集群的理解2.&nbsp;redis的数据类型有哪些3.&nbsp;你提到了有序集合zset,那请说一下zset的底层是什么数据结构(说这个我不太清楚,说了一下推测应该和redis的索引是一样的,是跳表)4.&nbsp;redis主从和集群可以保证数据一致性吗&nbsp;(回答不能,通过日志同步,存在脑裂等问题)5.&nbsp;项目中哪一块用到了redis,mysql和redis在项目中怎么确保数据一致性的&nbsp;(回答先更新数据库然后删除缓存,拓展了一下延迟双删)SpringCloud:1.&nbsp;了解SpringCloud吗,说一下他和SpringBoot的区别&nbsp;(直接道歉,回答springcloud还不太了解,需要后续进一步学习,然后说我理解springclod就是可以是业务更加精细化,分模块实现,而springboot更加整体&nbsp;(瞎说的))最后问了一下觉得自己还需要补充哪些知识:说了一下微服务和设计模式最后:面试官说感觉基础还是挺牢靠的,但是做的项目是一个简单的单体项目,所以体会不到分布式的一些场景,导致对这一块理解不深刻,建议我找相关项目跟着做一下。反问:技术方面感谢刚刚给的建议,然后问了一下有几面,说三面,两轮技术和一轮hr,二面和hr面可能合成一面,一两周左右通知&nbsp;(现在互联网找个实习都要三面了)。
点赞 评论 收藏
转发
8 16 评论
分享
牛客网
牛客企业服务