阿里笔试 阿里智能信息 0516

笔试时间:2025年5月16日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

给定一个长度为n的数组a = {a1, a2, ..., an},且保证n为偶数。 从中选出一个长度为n/2的子序列b,其余元素组成子序列c,长度同样为n/2。 请你最大化 ∑(b[i] - c[i])(i从1到n/2)的值,并输出该最大值。 子序列为从原数组中删除任意个(可以为零,可以为全部)元素得到的新数组。

现在,对于给出的字符串和整数 p,请你直接输出和声!

输入描述

第一行输入一个整数n (1 ≤ n ≤ 2×10^5),表示数组长度。

第二行输入n个整数a1, a2, ..., an (-10^9 ≤ ai ≤ 10^9),表示数组a的各个元素。

输出描述

输出一个整数,表示所能获得的最大值。

样例输入

4

2 3 1 4

样例输出

4

解释: 选取b = {3, 4},c = {2, 1},此时 ∑(b[i] - c[i]) = (3 - 2) + (4 - 1) = 4。

参考题解

将数组按降序排序,取前 n/2 个元素构成 b,其余构成 c。 设 b 的和为 T,总和为 S,则 sum(b[i] - c[i]) = T - (S - T) = 2*T - S。

C++:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<ll> a(n);
    ll S = 0;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        S += a[i];
    }
    sort(a.begin(), a.end(), greater<ll>());
    ll T = 0;
    for(int i = 0; i < n/2; i++){
        T += a[i];
    }

    cout << (2 * T - S) << "\n";
    return 0;
}

Java:

// Java 版本
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine().trim());
        long[] a = new long[n];
        StringTokenizer st = new StringTokenizer(br.readLine());
        long S = 0;
        for (int i = 0; i < n; i++) {
            a[i] = Long.parseLong(st.nextToken());
            S += a[i];
        }
        // 升序排序
        Arrays.sort(a);
        // 取最大的 n/2 个元素之和
        long T = 0;
        for (int i = n - 1; i >= n / 2; i--) {
            T += a[i];
        }
        System.out.println(2 * T - S);
    }
}

Python:

# Python 版本
import sys

data = sys.stdin.read().split()
n = int(data[0])
# 接下来的 n 个数
a = list(map(int, data[1:1+n]))

S = sum(a)
# 降序排序
a.sort(reverse=True)
# 求前 n//2 个最大元素之和
T = sum(a[:n//2])

print(2 * T - S)

第二题

Tk有一个正整数n,Tk想知道有多少三元组(x, y, z) 满足x × y - z = n,其中x, y, z都为小于n的正整数。

输入描述

输入一个整数n (1 ≤ n ≤ 10^6) 如题意。

输出描述

输出一个整数表示满足条件的三元组个数。

样例输入

5

样例输出

5

解释: 满足条件的三元组有(2, 3, 1),(2, 4, 3),(3, 2, 1),(3, 3, 4),(4, 2, 3)。

参考题解

我们要求 x,y,z ∈ [1, n-1] 且 xy - z = n 等价于 z = xy - n 且 1 ≤ z ≤ n-1 即 n+1 ≤ x*y ≤ 2n-1 对于每个 x,从 ceil((n+1)/x) 到 floor((2n-1)/x) 的 y 都满足条件 并且 y 还要在 [1, n-1] 范围内 所以枚举 x,计算 ymin = max(1, ceil((n+1)/x)),ymax = min(n-1, floor((2n-1)/x)) 若 ymin ≤ ymax,则有 ymax - ymin + 1 个合法 y,对应每个 y 有唯一 z 累加所有 x 的合法个数即可。

C++:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll n;
    cin >> n;
    ll ans = 0;
    for (ll x = 1; x < n; x++) {
        ll ymin = (n + 1 + x - 1) / x;       
        ll ymax = (2 * n - 1) / x;           
        ymin = max<ll>(ymin, 1);
        ymax = min<ll>(ymax, n - 1);
        if (ymin <= ymax) {
            ans += (ymax - ymin + 1);
        }
    }
    cout << ans << "\n";
    return 0;
}

Java:

// Java 版本
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        long n = Long.parseLong(br.readLine().trim());
        long ans = 0;
        for (long x = 1; x < n; x++) {
            // 计算 ymin = ceil((n+1)/x)
            long ymin = (n + 1 + x - 1) / x;
            // 计算 ymax = floor((2n-1)/x)
            long ymax = (2 * n - 1) / x;
            ymin = Math.max(ymin, 1L);
            ymax = Math.min(ymax, n 

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

牛客848095834号:举报了
点赞 评论 收藏
分享
05-29 22:11
门头沟学院 Java
Elastic90:抛开学历造假不谈,这公司的招聘需求也挺怪的,Java开发还要求你有图文识别、移动端开发和c++的经验,有点逆天了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务