【春招筆試】2025.05.11阿里云研發(fā)崗春招改編真題
? 春招備戰(zhàn)指南 ?
?? 學(xué)習(xí)建議:
- 先嘗試獨(dú)立解題(建議用時:90分鐘/套)
- 對照解析查漏補(bǔ)缺
?? 題面描述背景等均已深度改編,做法和題目本質(zhì)基本保持一致。
?? 感謝各位朋友們的訂閱,你們的支持是我們創(chuàng)作的最大動力
?? 目前本專欄已經(jīng)上線60+套真題改編解析,后續(xù)會持續(xù)更新的
春秋招合集 -> 互聯(lián)網(wǎng)必備刷題寶典??
題目一:音樂譜曲的回響效果
1??:解析輸入字符串,識別小節(jié)結(jié)構(gòu)和內(nèi)容
2??:根據(jù)回響規(guī)則,對每個小節(jié)生成對應(yīng)的回響效果
3??:處理長度限制和下劃線填充
難度:中等
這道題目要求根據(jù)特定規(guī)則為音樂片段生成回響效果。關(guān)鍵在于理解回響生成的規(guī)則:在每個小節(jié)前添加 p 個下劃線,然后截取與原小節(jié)相同長度的部分。通過對字符串的處理和操作,可以高效地生成符合規(guī)則的回響效果。
題目二:網(wǎng)格信息矩陣變換
1??:理解反對角線的定義和反轉(zhuǎn)操作
2??:遍歷所有可能的反對角線
3??:收集并反轉(zhuǎn)元素,然后重新填回原位置
難度:中等
這道題目考察對二維矩陣的操作和變換。通過識別并收集每條反對角線(滿足 j-i 為常數(shù)的元素)上的元素,將它們反轉(zhuǎn)后重新填回原位置,可以實(shí)現(xiàn)特定的矩陣變換效果。該解法具有 O(n×m) 的時間復(fù)雜度。
題目三:景區(qū)觀光路線規(guī)劃
1??:使用并查集維護(hù)景點(diǎn)連通性
2??:按吸引力指數(shù)從小到大處理所有景點(diǎn)
3??:統(tǒng)計(jì)精品路線的數(shù)量,包括單點(diǎn)路徑和雙端點(diǎn)路徑
難度:中等偏難
這道題目需要理解"精品路線"的定義,并找到一種高效的方法來統(tǒng)計(jì)符合條件的路徑數(shù)量。通過使用并查集按吸引力指數(shù)從小到大處理景點(diǎn),可以有效地處理連通性并計(jì)算路徑數(shù)量。該解法的時間復(fù)雜度為 O(n log n)。
01. 音樂譜曲的回響效果
問題描述
小毛是一位音樂制作人,他正在研究一種名為"回響"的音樂效果。在他的音樂編輯軟件中,音樂片段用字符串表示,僅由小寫字母和連接線'-'構(gòu)成。每個音樂片段用豎線'|'來劃分小節(jié),例如,|do-do-re|re---|表示兩個小節(jié),第一個小節(jié)長度為8字符("do-do-re"),第二個小節(jié)長度為5字符("re---")。
小毛希望為原始音樂創(chuàng)建回響效果?;仨懙囊?guī)則如下:
- 回響與原音樂具有相同數(shù)量的小節(jié),且每個小節(jié)長度與原音樂對應(yīng)小節(jié)相同
- 回響比原音樂晚
個長度單位出現(xiàn)
- 回響尚未出現(xiàn)的部分用下劃線'_'填充
- 如果回響超出小節(jié)范圍,則直接截?cái)?/li>
- 回響的生成方法是:先在每個小節(jié)前面添加
個下劃線,然后截取與原小節(jié)相同長度的部分
小毛現(xiàn)在需要你根據(jù)給定的原始音樂和參數(shù) ,自動生成相應(yīng)的回響效果。
輸入格式
第一行輸入兩個整數(shù) 、
(
;
),分別表示原始音樂字符串的總長度(包括 | 在內(nèi))和回響延遲的長度。
接下來若干行,一共輸入 個字符,表示原始音樂字符串。
保證每行的首末均為豎線(|),每個小節(jié)的長度至少為 1,小節(jié)中的字符僅為小寫字母和連接線(-)。
輸出格式
根據(jù)輸入,輸出若干行,表示生成的回響音樂字符串。
樣例輸入
16 2
|do-do-re|re---|
15 0
|ciallo|
|-|
|--|
7 2
|-|
|--|
16 2
|do-do-re|mi---|
樣例輸出
|__do-do-|__re-|
|ciallo|
|-|
|--|
|_|
|__|
|__do-do-|__mi-|
樣例1 | 第一個小節(jié)的回響:原小節(jié)"do-do-re"前添加2個下劃線變?yōu)?__do-do-re",截取8個字符得到"__do-do-";第二個小節(jié)的回響:原小節(jié)"re---"前添加2個下劃線變?yōu)?__re---",截取5個字符得到"__re-"。 |
樣例2 | 當(dāng)延遲p=0時,回響與原音樂完全相同。 |
樣例3 | 小節(jié)長度較短的情況下,回響可能只包含下劃線。第一個小節(jié)長1,添加2個下劃線后截取1個,變?yōu)?_";第二個小節(jié)長2,添加2個下劃線后截取2個,變?yōu)?__"。 |
樣例4 | 與樣例1類似,但第二個小節(jié)的原內(nèi)容為"mi---"。 |
數(shù)據(jù)范圍
- 保證每個小節(jié)長度至少為1
題解
這道題考查的是字符串處理,特別是如何根據(jù)規(guī)則生成新的字符串。
解題的關(guān)鍵在于理解"回響"的生成規(guī)則:對于每個小節(jié),我們需要在前面添加 個下劃線,然后截取與原小節(jié)相同長度的部分作為回響。
解題步驟如下:
- 首先,我們需要讀取整個輸入,將其按小節(jié)分割。小節(jié)的邊界由'|'標(biāo)記。
- 對于每個小節(jié),我們提取出小節(jié)內(nèi)容(不含邊界的'|')。
- 計(jì)算小節(jié)的長度
。
- 創(chuàng)建回響:添加
個下劃線(因?yàn)榧词?
很大,超過小節(jié)長度的部分也會被截?cái)啵?/li>
- 然后添加原小節(jié)內(nèi)容,并截取前
個字符作為最終的回響。
- 在回響前后添加'|'并輸出。
時間復(fù)雜度分析:我們只需要遍歷一次輸入字符串,對每個字符進(jìn)行常數(shù)時間的處理,所以時間復(fù)雜度是 ,其中
是輸入字符串的長度??臻g復(fù)雜度也是
,我們需要存儲輸入字符串和生成的回響字符串。
注意:雖然 可能高達(dá)
,但實(shí)際添加的下劃線數(shù)量不會超過小節(jié)長度,所以不會導(dǎo)致空間問題。
參考代碼
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 讀取輸入
n, p = map(int, input().split())
sections = []
total_len = 0
# 讀取所有行,累計(jì)長度直到達(dá)到n
while total_len < n:
line = input()
if line:
sections.append(line)
total_len += len(line)
# 處理每個小節(jié)生成回響
for i, section in enumerate(sections):
# 提取小節(jié)內(nèi)容(不含邊界的'|')
section_len = len(section) - 2 # 減去兩端的'|'
section_content = section[1:-1]
# 創(chuàng)建回響:添加下劃線并截取合適長度
underscore_count = min(p, section_len) # 添加的下劃線數(shù)量
echo = '_' * underscore_count + section_content
echo = echo[:section_len] # 截取與原小節(jié)相同長度
# 輸出帶邊界的回響
print(f"|{echo}|", end="")
if i < len(sections) - 1:
print() # 除最后一個小節(jié)外,每個小節(jié)后換行
- Cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int main() {
// 加速輸入
ios::sync_with_stdio(false);
cin.tie(nullptr);
// 讀取輸入
ll n, p;
cin >> n >> p;
string line;
vector<string> segs; // 存儲所有小節(jié)
ll total = 0;
// 讀取每一行,累計(jì)長度直到達(dá)到n
while (total < n && getline(cin, line)) {
if (line.empty()) continue; // 跳過空行
segs.push_back(line);
total += line.size();
}
// 處理每個小節(jié)
for (size_t i = 0; i < segs.size(); i++) {
string &s = segs[i];
int len = s.size() - 2; // 小節(jié)長度(不含兩端的'|')
string content = s.substr(1, len); // 小節(jié)內(nèi)容
// 創(chuàng)建回響
ll ucount = min<ll>(p, len); // 添加的下劃線數(shù)
string echo = string(ucount, '_') + content;
echo = echo.substr(0, len); // 截取與原小節(jié)相同長度
// 輸出帶邊界的回響
cout << '|' << echo << '|';
if (i + 1 < segs.size()) cout << '\n'; // 除最后一個小節(jié)外,每個小節(jié)后換行
}
return 0;
}
- 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));
String[] firstLine = br.readLine().split(" ");
// 讀取輸入
long n = Long.parseLong(firstLine[0]);
long p = Long.parseLong(firstLine[1]);
List<String> segs = new ArrayList<>();
long total = 0;
// 讀取每一行,累計(jì)長度直到達(dá)到n
String line;
while (total < n && (line = br.readLine()) != null) {
if (line.isEmpty()) continue;
segs.add(line);
total += line.length();
}
// 處理每個小節(jié)
for (int i = 0; i < segs.size(); i++) {
String s = segs.get(i);
int len = s.length() - 2; // 小節(jié)長度(不含兩端的'|')
String content = s.substring(1, len + 1); // 小節(jié)內(nèi)容
// 創(chuàng)建回響
int ucount = (int)Math.min(p, len); // 添加的下劃線數(shù)
StringBuilder echo = new StringBuilder();
for (int j = 0; j < ucount; j++) {
echo.append('_');
}
echo.append(content);
// 截取與原小節(jié)相同長度
if (echo.length() > len) {
echo = new StringBuilder(echo.substring(0, len));
}
// 輸出帶邊界的回響
System.out.print("|" + echo + "|");
if (i < segs.size() - 1) {
System.out.println(); // 除最后一個小節(jié)外,每個小節(jié)后換行
}
}
}
}
02. 網(wǎng)格信息矩陣變換
問題描述
小基正在設(shè)計(jì)一個數(shù)據(jù)可視化系統(tǒng),需要對信息矩陣進(jìn)行特殊的變換處理。他定義了一種"反對角線反轉(zhuǎn)"操作:對于一個 的網(wǎng)格矩陣,將每條反對角線(即滿足
為常數(shù)的所有單元格)上的元素按照從右上到左下的順序反轉(zhuǎn)排列。
更具體地說,對于網(wǎng)格中所有滿足 的單元格(其中
是一個常數(shù)),收集這些單元格上的所有元素,然后將它們反轉(zhuǎn)后重新填回原來的位置。這個操作需要對所有可能的
值(從
到
)都執(zhí)行一次。
小基想知道,對于給定的初始網(wǎng)格矩陣,執(zhí)行"反對角線反轉(zhuǎn)"操作后的結(jié)果是什么。
輸入格式
第一行輸入兩個正整數(shù) 、
(
),表示網(wǎng)格的行數(shù)和列數(shù)。
接下來 行,每行輸入
個正整數(shù)
(
),表示網(wǎng)格中第
行第
列的元素值。
輸出格式
輸出 行,每行
個整數(shù),表示執(zhí)行"反對角線反轉(zhuǎn)"操作后的網(wǎng)格矩陣。
樣例輸入
2 3
1 3 2
4 6 5
樣例輸出
6 5 2
4 1 3
樣例1 | 原矩陣為: 1 3 2 4 6 5 反對角線包括:(0,0)-(1,-1)即只有元素1;(0,1)-(1,0)為元素3和4,反轉(zhuǎn)后變?yōu)?和3;(0,2)-(1,1)為元素2和6,反轉(zhuǎn)后變?yōu)?和2;(2,1)即只有元素5。所以變換后的矩陣為: 6 5 2 4 1 3 |
數(shù)據(jù)范圍
題解
這道題要求我們實(shí)現(xiàn)一種特殊的矩陣變換操作,即"反對角線反轉(zhuǎn)"。理解這個操作是解題的關(guān)鍵。
在一個矩陣中,反對角線是指那些滿足 的單元格集合,其中
是一個常數(shù)。例如,當(dāng)
時,反對角線包括 (0,1), (1,2), (2,3) 等位置的元素。題目要求我們對每條反對角線上的元素進(jìn)行反轉(zhuǎn),即將它們按照從右上到左下的順序倒過來排列。
解題思路如下:
- 遍歷所有可能的
值,即從
到
。
- 對于每個
,收集滿足
的所有單元格位置和對應(yīng)的元素值。
- 將收集到的元素反轉(zhuǎn)排序。
- 將反轉(zhuǎn)后的元素重新填回對應(yīng)的位置。
時間復(fù)雜度分析:我們需要遍歷矩陣中的每個元素一次,對于每條反對角線,我們需要 的時間來收集和反轉(zhuǎn)元素??偣灿?
條反對角線,因此總時間復(fù)雜度為
。
空間復(fù)雜度:我們需要額外的空間來存儲結(jié)果矩陣和臨時收集的元素,因此空間復(fù)雜度為 。
參考代碼
- Python
import sys
input = lambda: sys.stdin.readline().strip()
# 讀取輸入
n, m = map(int, input().split())
grid = []
for _ in range(n):
row = list(map(int, input().split()))
grid.append(row)
# 初始化結(jié)果矩陣
result = [[0 for _ in range(m)] for _ in range(n)]
# 對每條反對角線進(jìn)行處理
for k in range(-(n-1), m):
# 收集當(dāng)前反對角線上的元素和位置
diag = []
pos = []
for i in range(n):
j = i + k
if 0 <= j < m:
diag.append(grid[i][j])
pos.append((i, j))
# 反轉(zhuǎn)元素
diag.reverse()
# 將反轉(zhuǎn)后的元素填回原位置
for idx, (i, j) in enumerate(pos):
result[i][j] = diag[idx]
# 輸出結(jié)果
for row in result:
print(*row)
- Cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
// 讀取輸入矩陣
vector<vector<long long>> grid(n, vector<long long>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> grid[i][j];
}
}
// 初始化結(jié)果矩陣
vector<vector<long long>>
剩余60%內(nèi)容,訂閱專欄后可繼續(xù)查看/也可單篇購買
互聯(lián)網(wǎng)刷題筆試寶典,這里涵蓋了市面上大部分的筆試題合集,希望助大家春秋招一臂之力