2021招商银行提前批Fin Tech训练营笔试题目(研发通道)

时间:2021-04-28

1.欢迎入营

题目描述

训练营同学来自n(1≤n≤105)个城市,每个城市的同学人数分别为 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an(1≤ a n a_n an≤109)。小Z将派出n辆车迎接同学。同一个城市的同学需要坐同一辆车,一辆车只能载来自同一个城市的同学,一辆车只能跑一次,且不能超过每辆车的载客量 b 1 , b 2 , … , b n ( 1 ≤ b n ≤ 109 ) b_1,b_2, …, b_n(1≤b_n≤109) b1,b2,,bn(1bn109)。请问有多少种不同的方式把这n个城市的同学安排到这n辆车?

输入描述

输入的第一行包含n。第二行包含n个空格分隔的整数a1,a2,…,an。第三行包含n个空格分隔的整数b1,b2, …, bn。

输出描述

输出满足条件的方案数,结果对100000007取模。

示例1
//输入
4
1 2 3 4
2 4 3 4
//输出
8
题解代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn = 1e5+10;
const ll mod = 100000007;
ll ans=1;
ll a[maxn];
ll b[maxn];
int n;
int get_id(ll x)
{
    int lb=1,ub=n,mid,ans=-1;
    while(ub>=lb)
    {
        mid=(lb+ub)/2;
        if(b[mid]>=x)
        {
            ans=mid; ub=mid-1;
        }
        else lb=mid+1;
    }  
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
    sort(a+1,a+1+n);
    sort(b+1,b+1+n);
    ll nd=1;
    for(int i=n;i;i--)
    {
        ll pos=(ll)get_id(a[i]);
        if(pos==-1)
        {
            ans=0;
            break;
        }
        pos=n-pos+1;
        if(pos<nd)
        {
            ans=0;
            break; 
        }  
        ans=ans*(pos-(nd-1))%mod;
        nd++;
    }  
    printf("%lld",ans);
    return 0;
}

2.欢送回家

题目描述

小Z为训练营同学预订了n(1≤n≤500)个回程航班,每个航班的同学数依次为a1,a2,…,an(1≤ai≤106)。现在只有一个司机,司机需要严格按照航班顺序依次将第1到第n个航班的同学送往机场。该司机可从租车公司租到任意载客量的车,但是最多只能租g次(1<=g<=n),并且每次只能租1辆。假设司机用载客量为m的车送ai个同学到机场(当然要求不超载),那么就造成了m-ai的载量浪费。请问该司机送完所有批次同学到机场后,最低的载量浪费是多少?

输入描述

第一行包含n和g

第二行n个整数a1,a2,…,an

输出描述

一个整数,总浪费载量的最小值

示例
//输入
6 3
7 9 8 2 3 2
//输出
3
//说明
提示:一开始租载客量7的车,送完第一批后,租载客量9的车,然后一直到送完第4批同学,再租载客量3的车,总载量浪费为(7-7)+(9-9)+(9-8)+(3-2)+(3-3)+(3-2)= 3
题解代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn = 510;
const ll mod = 100000007;
const int INF = 1e9;
int n,m;
int a[maxn];
int sum[maxn],Max[maxn][maxn];
int dp[maxn][maxn];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    for(int i=1;i<=n;i++)   
    {
        Max[i][i]=a[i];
        for(int j=i+1;j<=n;j++)
        Max[i][j]=max(Max[i][j-1],a[j]);
    }
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
            dp[i][j]=INF;
    dp[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            for(int k=0;k<i;k++)
                dp[i][j+1]=min(dp[i][j+1],dp[k][j]+ Max[k+1][i]*(i-k) - (sum[i]-sum[k]) ); 
        }
    }
    int ans=INF;
    for(int j=0;j<=m;j++) ans=min(ans,dp[n][j]);
    printf("%d",ans);
    return 0;
}

3. 训练营分组

题目描述

小Z组织训练营同学进行一次拔河比赛,要从n(2≤n≤60,000)个同学中选出两组同学参加(两组人数可能不同)。对每组同学而言,如果人数超过1人,那么要求该组内的任意两个同学的体重之差的绝对值不超过k(包含k)。问最多有几个同学能参加比赛?

输入描述

第一行为两个整数n和k( 0 ≤ k ≤ 1 0 9 0≤k≤10^9 0k109

接下来是n行,每行一个正整数,表示每个同学的体重,保证均为正整数且不超过 1 0 9 10^9 109

输出描述

一个正整数,最多参与的人数

示例
//输入
5 2
20
3
16
9
5
//输出
3
题解代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn = 1e5+10;
const ll mod = 100000007;
int n;
ll a[maxn];
ll k;
ll Max[maxn];
ll ans;
ll mMax[maxn];
void wk(int x)
{
    int mid,bns=x,lb=x,ub=n;
    while(ub>=lb)
    {
        mid=(lb+ub)/2;
        if(a[mid]-a[x]<=k)
        {
            bns=mid; lb=mid+1;
        }
        else ub=mid-1;
    }
    Max[x]=bns;
}
int main()
{
    scanf("%d%lld",&n,&k);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++) wk(i);
    for(int i=n;i;i--) mMax[i]=max(mMax[i+1],Max[i]-i+1);
    for(int i=1;i<=n;i++)
    {
        ans=max(ans,(Max[i]-i+1) + mMax[(int)Max[i]+1]);
    }
    printf("%lld",ans);
    return 0;
}

以上代码为夏令营排名第一的大佬编写,真的是太强了!!!!用时超短,第一题5分钟就写完了,太强了!!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

USTC暖暖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值