2020网易笔试题

第一题

小易是班级的英语课代表,他想开发一款软件来处理班上同学的成绩,同学们在该软件上输入自己的编号,就可以得到一个百分数,表示自己的成绩在班上的位置:“成绩超过了班级x%的同学”,设这个百分数为p,考虑s分,则计算公式为p=(分数不超过s的人数-1)/总人数 * 100%,请你设计一下这个软件;
输入描述:第一行一个整数n,表示班级人数;
第二行共n个自然数,第i个数表示第i位同学的成绩ai;
第三行一个整数q,表示查询的次数;
接下来q行,每行一个数x,表示询问第i位同学的成绩百分数;
输出描述:
每询问一次输出对应的成绩百分数,不需要输出百分号,输出四舍五入保留六位小数。
示例:
输入
3
100 98 87
3
1
2
3
输出
66.666667
33.333333
0.000000

分析

简单模拟一下就好了

代码

#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;
typedef pair<int,int> ppp;

int n,sum;
int score[10010];
int main()
{
    cin>>n;
    for (int i=1 ; i<=n ; i++)
        cin>>score[i];
    int q,x; cin>>q;
    while (q--){
        cin>>x;
        sum = 0;
        for (int i=1 ; i<=n ; i++){
            if (score[i] <= score[x] && i != x){
                sum++;
            }
        }
        printf("%.6f\n",sum*100.0/n);
    }
    return 0;
}

第二题

小易有一个长度为n的数字数组a1,a2,a3,…an.
能否用这n个数字构成一个环,使得环中的每一个数字都小于它相邻的两个数字的和?
输入描述:第一行包含一个整数T,表示测试用例的组数;
对于每个测试用例,第一行为一个整数n,表示数字个数,第二行为n个整数,表示数组a,其中 3<=n<=10^5 1<=ai<=10^5;
输出描述:输出有t行,每行输出YES或者NO表示能否成环。
示例1:
输入
1
5
17 6 17 11 17
输出
YES
示例2:
输入
1
3
1 2 4
输出
NO

分析

实际上,对于一个升序数组来说,每一个数字都小于它左右两个数字的和,所以我们先把 a[] 排序,那么不能成环的情况就只有a[n] >= a[1]+a[n-1] ,这样提交以后并没能过掉全部测试点,此题最容易卡住的点在于如果交换 a[n] 和 a[n-1] 的位置是有可能成环的,判断条件为 a[n] >= a[1]+a[n-1] && a[n] >= a[n-1] + a[n-2]。

代码

#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;

int n;
LL a[100010];
int main()
{
    int t; cin>>t;
    while (t--){
        cin>>n;
        for (int i=0 ; i<n ; i++)
            cin>>a[i];
        sort(a,a+n);
        int flag = 0;
        if (a[n-1] >= a[n-2]+a[0] && a[n-1] >= a[n-2]+a[n-3])
            printf("NO");
        else printf("YES");
        cout<<endl;
    }
    return 0;
}

第三题

小易给你一个包含n个数字的数组a1,a2,…,an,你可以对这个数组进行任意次以下交换操作:对于数组中的两个元素ai 和 aj,如果ai+aj是奇数,就可以交换它们。
操作次数不限,小易想知道所有能够得到的数组中字典序最小的是哪一个。
输入描述:第一行一个整数n;
第二行n个整数表示数组a,输入保证 1<=n<=10^5 ,1<=ai<=10^9
输出描述:n个整数,每两个之间用一个空格分隔,表示得到的字典序最小的数组。
示例1:
输入
4
7 3 5 1
输出
7 3 5 1
示例2:
输入
10
53941 38641 31525 75864 29026 12199 83522 58200 64784 80987
输出
12199 29026 31525 38641 53941 58200 64784 75864 80987 83522

分析

此题暂时没能想出完全正确的答案,但是简单的重构一下快排的判断条件可以通过70%的数据,基本上可以接受了,毕竟笔试也没有要求必须AC。

代码

#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;
typedef pair<int,int> ppp;

bool cmp(LL a,LL b)
{
    if ((a+b)%2)
        return a < b;
}
int n;
LL a[100010];
int main()
{
    cin>>n;
    for (int i=0 ; i<n ; i++)
        cin>>a[i];
    sort(a,a+n,cmp);
    for (int i=0 ; i<n ; i++){
        if (i) printf(" ");
        printf("%d",a[i]);
    }
    cout<<endl;
    return 0;
}

第四题

小易在维护数据的时候遇到了一个需求,有一系列数据,构成了一个长度为n的数字序列,接下来小易会做q次操作。
每次操作有一个查询的数字x,小易要将序列数据中所有大于等于x的数字都减一,并输出在本次操作中有多少个数字被减一了。
小易请你帮他设计一下。
输入描述:第一行为n q,表示数字个数和操作个数 1<=n,q<=200000;
接下来一行有n个数,表示初始序列a;
接下来q行,每行一个数x,进行查询 1<=ai,x<=n;
输出描述:每行输出一个数字表示对应查询的结果。
示例1:
输入
4 3
1 2 3 4
4
3
1
输出
1
2
4
示例2:
输入
3 2
1 2 3
3
3
输出
1
0

分析

模拟题,写的时候尽可能的进行优化,先计算一下所有数字的数量存在data_sum[]中,维护一下当前序列的最大值maxn,查询的时候如果查询数字x大于maxn,就输出0;不大于的话,data_sum[x-1] += data_sum[x],然后把从 x 到 maxn 的 data_sum[]全加起来就是操作数,操作过后 i 从 x 到 maxn-1 有 data_sum[i] = data_sum[i+1]

代码

#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef long long LL;
typedef pair<int,int> ppp;

int n,q,x,maxn;
int data[200010];
int data_sum[200010];
int sum[200010];
int main()
{
    cin>>n>>q;
    memset(data_sum,0,sizeof data_sum);
    for (int i=0 ; i<n ; i++){
        cin>>data[i];
        data_sum[data[i]]++;
        maxn = max(maxn,data[i]);
    }

    while (q--){
        cin>>x;
        int ans = 0;
        if (x <= maxn){
            data_sum[x-1] += data_sum[x];
            for (int i=x; i<=maxn ; i++){
                ans += data_sum[i];
                if (i<maxn) data_sum[i] = data_sum[i+1];
            }

            data_sum[maxn] = 0;
            maxn--;
        }

        cout<<ans<<endl;
    }
    return 0;
}

你可能感兴趣的:(C++笔试编程题)