携程2025.8.26秋招笔试题解
携程2025.8.26秋招笔试题解
t1
签到题,手动模拟
python代码
import sys
def main():
n = int(input().strip())
cur = 0
num = 0
while True:
s = str(num)
if cur + len(s) >= n:
print(s[n - cur - 1])
break
else:
cur += len(s)
num += 2
if __name__ == "__main__":
main()
cpp代码
#include <iostream>
#include <string>
int n;
int main() {
std::cin >> n;
int cur = 0, num = 0;
std::string s;
while (true) {
s = std::to_string(num);
if (cur + s.length() >= n) {
std::cout << s[n - cur - 1];
break;
}
else {
cur += s.length();
num += 2;
}
}
return 0;
}
t2
既然和公约数有关,那么我们首先会想到分解质因数,想到分解质因数就会想到筛质数。
思路就是:
- 筛质数
- 根据筛选出的质数去求最大长度
- 筛选满足最大长度的质数,并且利用gcd去重
注意最后筛选的candidates来自于cover而不是primes,因为primes里面只有\(sqrt(n)\)以下的质数,而cover经过更新以后,可以包含全量的满足条件的质数(即包括了大于\(sqrt(n)\)的部分)
python代码
import sys, math
def select_primes(upper, flags, primes: list):
for i in range(2, upper):
if not flags[i]:
primes.append(i)
for pj in primes:
if pj > upper // i:
break
flags[pj * i] = True
if i % pj == 0:
break
def resolve(x, primes):
res = []
for pi in primes:
if x % pi == 0:
res.append(pi)
while x % pi == 0:
x //= pi
# 记得不要漏掉x本身是质数的情况
if x > 1:
res.append(x)
return res
def read_int():
with open('input.txt', 'r', encoding='utf-8') as file:
data = file.read().strip().split()
for i in data:
yield int(i)
def main():
it = iter(read_int())
n = next(it, 0)
print(n)
freqs = {}
_max = 0
# 没必要获取全部的输入,只要拿到>1的那部分就行了
for _ in range(n):
num = next(it)
if num <= 1:
continue
freqs[num] = freqs.get(num, 0) + 1
_max = max(_max, num)
if len(freqs.keys()) == 0:
print("0 0")
sys.exit(0)
# 筛质数
upper = math.isqrt(_max) + 1
prime_flag = [False] * (upper + 1)
primes: list[int] = []
select_primes(upper, prime_flag, primes)
# 分解质因数,求最大长度
cover = {} # 每个质数能覆盖几个元素
base = {} # 每个质数覆盖的元素组当中,各个元素的gcd是多少
for n, t in freqs.items():
for pi in resolve(n, primes):
cover[pi] = cover.get(pi, 0) + t
base[pi] = n if pi not in base else math.gcd(base[pi], n)
ans = max(cover.values(), default=1)
if ans == 1:
print(f"1 {len(freqs)}")
sys.exit(0)
# 统计答案
seen = set()
cnt = 0
candidates = [pi for pi in cover if cover[pi] == ans]
for pi in candidates:
if pi in seen:
continue
for qi in resolve(base[pi], primes):
seen.add(qi)
cnt += 1
print(f"{ans} {cnt}")
if __name__ == "__main__":
main()
cpp代码
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <array>
#include <vector>
#include <unordered_map>
#include <unordered_set>
constexpr int N = 2e6 + 5, M = 2e8 + 5;
int P = static_cast<int>(std::sqrt(M));
std::unordered_map<int, int> freqs, cover, base;
std::vector<int> primes, factors;
int n;
inline void select_primes(int upper) {
std::vector<char> flag (upper + 1, 0);
for (int i = 2; i <= upper; i++) {
if (!flag[i])
primes.emplace_back(i);
for (int j = 0; j < primes.size() && primes[j] <= upper / i; j++) {
flag[primes[j] * i] = true;
if (i % primes[j] == 0)
break;
}
}
}
void resolve(int x) {
factors.clear();
for (auto pi: primes) {
if (x % pi == 0) {
factors.push_back(pi);
while (x % pi == 0) {
x /= pi;
}
}
}
if (x != 1) {
factors.push_back(x);
}
}
int gcd(int x, int y) {
if (!y) {
return x;
}
return gcd(y, x%y);
}
int main() {
std::freopen("input.txt", "r", stdin);
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
// 没必要获取全部输入,只要>1的
int x, _max = 0;
std::cin >> n;
for (int i = 1; i <= n; i++) {
std::cin >> x;
if (x <= 1)
continue;
freqs[x]++;
_max = std::max(_max, x);
}
if(freqs.empty()) {
std::cout << "0 0";
return 0;
}
int upper = static_cast<int>(std::sqrt(_max)) + 1;
// 筛质数
select_primes(upper);
// 统计长度
int L = 0;
for (auto &pi: freqs) {
int key = pi.first;
resolve(key);
for (auto ai: factors) {
cover[ai] += pi.second;
if (base.find(ai) == base.end()) {
base[ai] = pi.first;
} else {
base[ai] = gcd(base[ai], pi.first);
}
}
}
for (auto &pi: cover) {
L = std::max(L, pi.second);
}
if (L == 1) {
std::cout << L << " " << freqs.size() << std::endl;
return 0;
}
std::unordered_set<int> seen;
int ans = 0;
// 注意这里是cover而不是primes
for (auto &pi: cover) {
if (seen.contains(pi.first))
continue;
if (cover[pi.first] < L) {
continue;
}
resolve(base[pi.first]);
for (auto &vi: factors) {
seen.insert(vi);
}
ans++;
}
std::cout << L << " " << ans << std::endl;
return 0;
}
t3
这道题介于POJ 2352 Stars和HH的项链之间
python code
# 其实r没有必要做离散化,浪费了性能
# 我们只需要压缩l的值域即可.
# 这个版本的离散化写得有问题,应该输入全部读完以后统一离散化,否则两个部分的输入值域不同,离散化结果也是错误的
import sys
import bisect
input = sys.stdin.readline
N = int(5e5 + 5)
M = int(1e9 + 5)
class TreeArr:
def __init__(self, len):
self.len = len
self.arr = [0] * (len + 1)
def update(self, pos, x):
while (pos <= self.len):
self.arr[pos] += x
pos += (pos & (-pos))
def query(self, pos):
res = 0
while pos:
res += self.arr[pos]
pos -= (pos & (-pos))
return res
def main():
n, m = tuple(map(int, input().strip().split()))
origin_vals = []
bacs: list[tuple] = []
for _ in range(n):
l, r = tuple(map(int, input().strip().split()))
origin_vals.append(l)
origin_vals.append(r)
bacs.append((l, r))
# 离散化
vals = sorted(set(origin_vals))
_max = len(vals)
func = lambda x: bisect.bisect_left(vals, x) + 1
for i in range(len(bacs)):
bacs[i] = (func(bacs[i][0]), func(bacs[i][1]))
bacs = sorted(bacs, key=lambda x: x[1])
origin_vals.clear()
# 记录查询
queries = []
for i in range(m):
l, r = tuple(map(int, input().strip().split()))
queries.append((i, l, r))
origin_vals.append(l)
origin_vals.append(r)
# 离散化
for i in range(len(queries)):
queries[i] = (queries[i][0], func(queries[i][1]), func(queries[i][2]))
queries = sorted(queries, key=lambda x: x[2])
tree_arr =TreeArr(_max)
idx = 0
ans = [0] * m
# 计算答案
for i in range(m):
qid, ql, qr = queries[i]
while idx < len(bacs) and bacs[idx][1] <= qr:
tree_arr.update(bacs[idx][0], 1)
idx += 1
ans[qid] = idx - tree_arr.query(ql - 1)
print("\n".join(map(str, ans)))
if __name__ == "__main__":
main()
cpp code
因为使用了vector,下标能从零开始就尽量从零开始吧。
// POJ 2352 Stars
#include <algorithm>
#include <array>
#include <cstdio>
#include <iterator>
#include <random>
#include <vector>
constexpr int N = 1e5 + 5, M = 1e9 + 5;
using PII = std::pair<int, int>;
std::vector<int> origin_vals;
std::vector<PII> bacs;
std::vector<std::tuple<int, int, int>> queries;
int n, m;
inline int lowbit(int x) {
return x & (-x);
}
struct TreeArr {
int len;
std::vector<int> arr;
TreeArr(int l): len(l) {
arr.resize(len + 1, 0);
}
void update(int pos, int x) {
while (pos <= len) {
arr[pos] += x;
pos += lowbit(pos);
}
}
int query(int pos) {
int res = 0;
while (pos) {
res += arr[pos];
pos -= lowbit(pos);
}
return res;
}
};
inline int mapping(std::vector<int> &a, int x) {
return (std::lower_bound(a.begin(), a.end(), x) - a.begin()) + 1;
}
int main() {
std::freopen("input.txt", "r", stdin);
scanf("%d%d", &n, &m);
int l, r;
bacs.resize(n);
queries.resize(m);
for (int i = 0; i < n; i++) {
scanf("%d%d", &l, &r);
origin_vals.push_back(l);
bacs[i] = {l, r};
}
for (int i = 0; i < m; i++) {
scanf("%d%d", &l ,&r);
origin_vals.push_back(l);
queries[i] = std::tuple{r, l, i};
}
// 离散化
std::sort(origin_vals.begin(), origin_vals.end());
origin_vals.erase(std::unique(origin_vals.begin(), origin_vals.end()), origin_vals.end());
for (int i = 0; i < n; i++) {
bacs[i].first = mapping(origin_vals, bacs[i].first);
}
for (int i = 0; i < m; i++) {
std::get<1>(queries[i]) = mapping(origin_vals, std::get<1>(queries[i]));
}
auto func = [](PII a, PII b)->bool {return a.second < b.second;};
std::sort(bacs.begin(), bacs.end(), func);
std::sort(queries.begin(), queries.end());
auto tree_arr = TreeArr(origin_vals.size());
int idx = 0;
std::vector<int> ans(m, 0);
for (int i = 0; i < m; i++) {
while (idx < n && bacs[idx].second <= std::get<0>(queries[i])) {
tree_arr.update(bacs[idx].first, 1);
idx++;
}
int t = std::get<2>(queries[i]);
ans[t] = idx - tree_arr.query(std::get<1>(queries[i]) - 1);
}
for (int i = 0; i < m; i++)
printf("%d\n", ans[i]);
return 0;
}

浙公网安备 33010602011771号