【笔试】备战秋招,每日一题|20230415携程研发岗笔试

news/2024/12/2 13:25:05/

前言

最近碰到一个专门制作大厂真题模拟题的网站 codefun2000,最近一直在上面刷题。今天来进行2023.04.15携程研发岗笔试,整理了一下自己的思路和代码。

比赛地址

A. 找到you

题意:

给定一个仅包含小写字母的 n × n n\times n n×n 的矩阵,问这个矩阵中所有 2 × 2 2\times 2 2×2 的矩阵中同时包含 you 三个字符的子矩阵数量。

数据范围: 1 ≤ n , m ≤ 1000 1\leq n, m\leq 1000 1n,m1000

题解:

暴力枚举每个 2 × 2 2\times 2 2×2 子矩阵,对于每个子矩阵,判断其之中是否同时存在 you 三个字符即可,共需要枚举 ( n − 1 ) × ( m − 1 ) (n - 1) \times (m - 1) (n1)×(m1) 个子矩阵。

时间复杂度分析: O ( n m ) O(nm) O(nm)

#include <bits/stdc++.h>
using namespace std;const int N = 1010;
char s[N][N];
int n, m;bool check(int i, int j) {int val = 0;for (int x = 0; x < 2; ++x)for (int y = 0; y < 2; ++y) {if (s[i + x][y + j] == 'y') val |= 1 << 0;if (s[i + x][y + j] == 'o') val |= 1 << 1;if (s[i + x][y + j] == 'u') val |= 1 << 2;}return val == 7;
}int main()
{scanf("%d%d", &n, &m);;for (int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);int ans = 0;for (int i = 1; i + 1 <= n; ++i)for (int j = 1; j + 1 <= m; ++j) {if (check(i, j)) ans += 1;}printf("%d\n", ans);return 0;
}

B. 最小公倍数

题意:

T T T 组数据,每组数据给定一个 n n n,现在问在 a + b = n a + b = n a+b=n 的情况下,使得 l c m ( a , b ) lcm(a, b) lcm(a,b) 最大的 a a a b b b 是多少?

数据范围: 1 ≤ T ≤ 1 0 5 , 2 ≤ n ≤ 1 0 13 1\leq T\leq 10^5, 2\leq n\leq 10^{13} 1T105,2n1013

题解:

T T T 组数据,而 T T T 最大为 1 0 5 10^5 105 ,则每组数据至多要在 O ( log ⁡ n ) O(\log n) O(logn) 的时间解决,因为这个题需要求 l c m lcm lcm,这个求解的复杂度是 O ( log ⁡ n ) O(\log n) O(logn) 的,
所以判断的操作得在 O ( 1 ) O(1) O(1) 时间复杂度内。

下面我们都认为 a ≤ b a \leq b ab
当两个数 a a a b b b ,满足 a + 1 = b a + 1 = b a+1=b ,那么此时 a a a b b b 互质, l c m ( a , b ) = a × b lcm(a, b) = a \times b lcm(a,b)=a×b

考虑奇数:将其拆分成 a = ⌊ n 2 ⌋ , b = ⌈ n 2 ⌉ a = \lfloor\frac{n}{2}\rfloor, b = \lceil\frac{n}{2}\rceil a=2n,b=2n,有 a + 1 = b a + 1 = b a+1=b,故此时最大的 l c m ( a , b ) lcm(a, b) lcm(a,b) 就是 a = ⌊ n 2 ⌋ , b = ⌈ n 2 ⌉ a = \lfloor\frac{n}{2}\rfloor, b = \lceil\frac{n}{2}\rceil a=2n,b=2n
考虑偶数:将其拆分成 a = n 2 , b = n 2 a = \frac{n}{2}, b = \frac{n}{2} a=2n,b=2n l c m ( a , b ) = n 2 lcm(a, b) = \frac{n}{2} lcm(a,b)=2n

因为 n n n 是偶数,所以拆分出必然是要么 a a a b b b 均为偶数,要么 a a a b b b 均为奇数。
这里有一个结论,对于正数 a , b , n a,b,n a,b,n,如果有 a + b = n a + b = n a+b=n,且 a a a b b b 均为奇数,则 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1

n = 2 n=2 n=2,只有一种拆分法: a = 1 , b = 1 a=1,b=1 a=1,b=1

n > 2 n>2 n>2,对于拆分 a = 1 , b = n − 1 , l c m ( 1 , n − 1 ) > l c m ( n 2 , n 2 ) a=1,b=n-1,lcm(1,n-1)>lcm(\frac{n}{2},\frac{n}{2}) a=1,b=n1lcm(1,n1)>lcm(2n,2n),所以 a = n 2 , b = n 2 a=\frac{n}{2},b=\frac{n}{2} a=2n,b=2n这个拆分必然不如其他任意一个拆分。

此外,下面的讨论都只针对大于 2 2 2 的偶数。

所以对于一个数 n n n,我们至多只需要考虑 2 2 2 个位置,因为其他位置都不如这些位置中的任意一个:

n 2 \frac{n}{2} 2n 为奇数,

  • a = n 2 − 1 , b = n 2 + 1 , l c m ( a , b ) = a × b g c d ( a , b ) = ( n 2 − 1 ) × ( n 2 + 1 ) 2 a = \frac{n}{2} - 1, b = \frac{n}{2} + 1, lcm(a,b)=\frac{a \times b}{gcd(a,b)}=\frac{(\frac{n}{2} - 1)\times (\frac{n}{2} + 1)}{2} a=2n1,b=2n+1,lcm(a,b)=gcd(a,b)a×b=2(2n1)×(2n+1),因为 b − a = 2 b-a=2 ba=2,且 a a a b b b 都是偶数,故 g c d ( a , b ) = 2 gcd(a,b)=2 gcd(a,b)=2
  • a = n 2 − 2 , b = n 2 + 2 , l c m ( a , b ) = a × b g c d ( a , b ) = ( n 2 − 2 ) × ( n 2 + 2 ) 1 a = \frac{n}{2} - 2, b = \frac{n}{2} + 2,lcm(a,b)=\frac{a \times b}{gcd(a,b)}=\frac{(\frac{n}{2} - 2)\times (\frac{n}{2} + 2)}{1} a=2n2,b=2n+2,lcm(a,b)=gcd(a,b)a×b=1(2n2)×(2n+2),因为 b − a = 4 b-a=4 ba=4,故公约数只能为 1 , 2 , 4 1,2,4 1,2,4,且 a a a b b b 都是奇数,故最大公约数只能为 1 1 1

n 2 \frac{n}{2} 2n 为偶数,

  • a = n 2 − 1 , b = n 2 + 1 , l c m ( a , b ) = a × b g c d ( a , b ) = ( n 2 − 1 ) × ( n 2 + 1 ) 1 a = \frac{n}{2} - 1, b = \frac{n}{2} + 1, lcm(a,b)=\frac{a \times b}{gcd(a,b)}=\frac{(\frac{n}{2} - 1)\times (\frac{n}{2} + 1)}{1} a=2n1,b=2n+1,lcm(a,b)=gcd(a,b)a×b=1(2n1)×(2n+1),因为 b − a = 2 b-a=2 ba=2,故公约数只能为 1 , 2 1, 2 1,2,且 a a a b b b 都是奇数,故 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1
  • a = n 2 − 2 , b = n 2 + 2 , l c m ( a , b ) = a × b g c d ( a , b ) = ( n 2 − 2 ) × ( n 2 + 2 ) g c d ( a , b ) ≥ 2 a = \frac{n}{2} - 2, b = \frac{n}{2} + 2,lcm(a,b)=\frac{a \times b}{gcd(a,b)}=\frac{(\frac{n}{2} - 2)\times (\frac{n}{2} + 2)}{gcd(a,b)\geq2} a=2n2,b=2n+2,lcm(a,b)=gcd(a,b)a×b=gcd(a,b)2(2n2)×(2n+2),因为 b − a = 4 b-a=4 ba=4,故公约数只能为 1 , 2 , 4 1,2,4 1,2,4,且 a a a b b b 都是偶数,故最大公约数至少为 2 2 2

上面已经说明了,对于本题中的 a + b = n a+b=n a+b=n a × b > ( a − 1 ) × ( b + 1 ) = a × b + a − b − 1 a \times b > (a - 1) \times (b + 1) = a \times b + a - b - 1 a×b>(a1)×(b+1)=a×b+ab1
因为 a − b − 1 < 0 a - b - 1 < 0 ab1<0,故 a × b > ( a − 1 ) × ( b + 1 ) a \times b > (a - 1) \times (b + 1) a×b>(a1)×(b+1)

n 2 \frac{n}{2} 2n 为奇数,
l c m ( n 2 − 1 , n 2 + 1 ) − l c m ( n 2 − 2 , n 2 + 2 ) = ( n 2 8 − 1 2 ) − ( n 2 4 − 4 ) = 28 − n 2 8 lcm(\frac{n}{2}-1,\frac{n}{2}+1)-lcm(\frac{n}{2}-2,\frac{n}{2}+2)=(\frac{n^2}{8}-\frac{1}{2})-(\frac{n^2}{4}-4)=\frac{28-n^2}{8} lcm(2n1,2n+1)lcm(2n2,2n+2)=(8n221)(4n24)=828n2,因为 n 2 \frac{n}{2} 2n 为奇数且 n > 2 n>2 n>2,故 n ≥ 6 n\geq6 n6,故 28 − n 2 8 < 0 \frac{28-n^2}{8}<0 828n2<0,故 l c m ( n 2 − 2 , n 2 + 2 ) > l c m ( n 2 − 1 , n 2 + 1 ) lcm(\frac{n}{2}-2,\frac{n}{2}+2)>lcm(\frac{n}{2}-1,\frac{n}{2}+1) lcm(2n2,2n+2)>lcm(2n1,2n+1)

n 2 \frac{n}{2} 2n 为偶数,
l c m ( n 2 − 1 , n 2 + 1 ) > l c m ( n 2 − 2 , n 2 + 2 ) lcm(\frac{n}{2}-1,\frac{n}{2}+1)>lcm(\frac{n}{2}-2,\frac{n}{2}+2) lcm(2n1,2n+1)>lcm(2n2,2n+2)

总结:

n n n 为奇数: a = ⌊ n 2 ⌋ , b = ⌈ n 2 ⌉ a = \lfloor\frac{n}{2}\rfloor, b = \lceil\frac{n}{2}\rceil a=2n,b=2n

n n n 为偶数:

  • n = 2 n = 2 n=2 a = 1 , b = 1 a=1,b=1 a=1,b=1
  • n 2 \frac{n}{2} 2n 为奇数, a = n 2 − 2 , b = n 2 + 2 a = \frac{n}{2} - 2, b = \frac{n}{2} + 2 a=2n2,b=2n+2
  • n 2 \frac{n}{2} 2n 为偶数, a = n 2 − 1 , b = n 2 + 1 a = \frac{n}{2} - 1, b = \frac{n}{2} + 1 a=2n1,b=2n+1

代码:

#include <bits/stdc++.h>
using namespace std;typedef long long ll;void solve() {ll n; scanf("%lld", &n);if (n & 1) {printf("%lld %lld\n", n / 2, n - n / 2);} else {if (n == 2) puts("1 1\n");if ((n / 2) & 1) {printf("%lld %lld\n", n / 2 - 2, n / 2 + 2);} else {printf("%lld %lld\n", n / 2 - 1, n / 2 + 1);}}}int main()
{int T;scanf("%d", &T);while (T--) {solve();}return 0;
}

C.魔法之树

题意:

给定一个 n n n 个点的树,问这棵树上任意一条简单路径,有起点和终点,这条路径上的点构成的二进制字符串对应的十进制数在 [ l , r ] [l, r] [l,r] 范围内的简单路径数。这里的简单路径长度至少为 1 1 1 ,即自己到自己不算在内

数据范围: 1 ≤ n ≤ 1000 , 1 ≤ l ≤ r ≤ 1 0 14 1\leq n\leq 1000, 1\leq l\leq r\leq {10^{14}} 1n1000,1lr1014

题解:
枚举以每个点作为起点,遍历完所有的其他 n − 1 n-1 n1 个点为终点,当遇到值大于 r r r ,则后面的点作为终点的简单路径构成的二进制字符串对应的十进制数都必然大于 r r r 了,不会再可能成为答案了。这里必须要及时判断,一方面可以剪枝,另一方面是为了避免爆 long long

时间复杂度: O ( n 2 ) O(n^2) O(n2)

代码:

#include <bits/stdc++.h>
using namespace std;typedef long long ll;const int N = 1010;
vector<int> g[N];
int n;
ll l, r;
char s[N];
int ans;void dfs(int cur, int u, int fa, ll val) {val = val * 2 + (s[u] - '0');if (val > r) return ;if (val >= l && u != cur) ans += 1;for (int v: g[u]) {if (v == fa) continue ;dfs(cur, v, u, val);}
}void solve() {scanf("%d%lld%lld", &n, &l, &r);scanf("%s", s + 1);for (int i = 1; i < n; ++i) {int a, b;scanf("%d%d", &a, &b);g[a].push_back(b);g[b].push_back(a);}ans = 0;for (int i = 1; i <= n; ++i) {dfs(i, i, 0, 0);}printf("%d\n", ans);
}int main()
{int T = 1;
//    scanf("%d", &T);while (T--) {solve();}return 0;
}

D.01串的回文子串

题意:

给定 n n n 个数 a i a_i ai,当 i i i 为奇数,表示生成 a i a_i ai1,当 i i i 为偶数,表示生成 a i a_i ai0。即生成一个长度为 ∑ i = 1 n a i \sum\limits_{i=1}^n a_i i=1nai 的序列 s s s s [ 1 , a 1 ] = 1 , s [ a 1 + 1 , a 2 ] = 0 , s [ a 2 + 1 , a 3 ] = 1 , s [ a 3 + 1 , a 4 ] = 0 , . . . s[1, a_1]=1,s[a_1+1,a_2]=0,s[a_2+1,a_3]=1,s[a_3+1,a_4]=0,... s[1,a1]=1,s[a1+1,a2]=0,s[a2+1,a3]=1,s[a3+1,a4]=0,... 。问这个序列中有多少个回文子串。答案对 1 0 9 + 7 10^9+7 109+7 取模

数据范围:
1 ≤ n ≤ 1000 , 1 ≤ a i ≤ 1 0 9 1\leq n\leq 1000,1\leq a_i\leq 10^9 1n1000,1ai109

题解:

可以将看成序列看成分为 n n n 块,每块内部都是连续的 0 0 0 1 1 1

考虑每块内部可以生成多少回文子串:一块内部有 x x x 个数,以第 i i i 个数结尾的回文子串数量为 i i i ,即 ∑ i = 1 x i = x × ( x + 1 ) 2 \sum\limits_{i=1}^xi=\frac{x\times (x+1)}{2} i=1xi=2x×(x+1)

再考虑包含第 i i i 块的回文子串数量。那么以第 i i i 块为回文子串中心,向左右扩展。当且仅当左右两个数都相同,会多生成一个回文子串。这个什么时候截止呢,假设我们当前 a [ i − 1 ] = a [ i + 1 ] , a [ i − 2 ] = a [ i + 2 ] , . . . a [ i − p ] = a [ i + p ] a[i-1]=a[i+1],a[i-2]=a[i+2],...a[i-p]=a[i+p] a[i1]=a[i+1],a[i2]=a[i+2],...a[ip]=a[i+p],但是 a [ i − p − 1 ] ≠ a [ i + p + 1 ] a[i-p-1]\neq a[i+p+1] a[ip1]=a[i+p+1],则生成的回文子串数为: m i n ( a [ i − p − 1 ] , a [ i + p + 1 ] ) + ∑ j = 1 p a [ j ] min(a[i-p-1],a[i+p+1])+\sum\limits_{j=1}^p a[j] min(a[ip1],a[i+p+1])+j=1pa[j]

时间复杂度: O ( n 2 ) O(n^2) O(n2)

代码:

#include <bits/stdc++.h>
using namespace std;const int N = 1010;
const int mod = 1e9 + 7;long long a[N];
int n;void solve() {long long ans = 0;scanf("%d", &n);for (int i = 1; i <= n; ++i) {scanf("%lld", &a[i]);ans = (ans + a[i] * (a[i] + 1) / 2) % mod;}for (int i = 2; i < n; ++i) {int L = i - 1, R = i + 1;while (L >= 1 && R <= n) {ans = (ans + min(a[L], a[R])) % mod;if (a[L] == a[R]) L -= 1, R += 1;else break;}}printf("%lld\n", ans);
}int main()
{int T = 1;
//    scanf("%d", &T);while (T--) {solve();}return 0;
}

http://www.ppmy.cn/news/53145.html

相关文章

Linux内核进程管理与调度:策略优化与实践分析

Linux内核进程管理与调度 一、前言二、进程管理和多进程调度2.1 进程标识符和控制块2.2 进程状态和转换2.3 进程间通信 三、单处理器下的Linux进程调度3.1 Linux进程调度器3.2 时间片轮转调度算法3.3 最短剩余时间优先调度算法3.4 其他调度算法的不足 四、多处理器下的Linux进程…

模型剪枝网络 Learning Efficient Network throung Network Slimming 简述

1. 概述 训练得到的特征图&#xff0c;并不是所有特征图都重要&#xff0c;另一方面&#xff0c;希望对权重执行策略&#xff0c;体现出权重之间的差异性&#xff0c;最终目的就是获得不同特征图中的channel sacling factors&#xff0c;表征了不同特征图的重要性 2. BN 采…

【LeetCode: 1143. 最长公共子序列 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

初识uniapp

创建小程序 依次点击HBuilderx 左上方的按钮&#xff1a;文件->新建->项目 然后打开该界面&#xff0c;输入项目名称&#xff0c;点击 浏览 按钮&#xff0c;可以选择项目保存的目录&#xff0c;这些完成后点击 创建 按钮就好了 比如小颖的项目名叫 &#xff1a;test-y…

SpringBoot中一个注解优雅实现重试Retry框架

目录: 1、简介2、实现步骤 1、简介 重试&#xff0c;在项目需求中是非常常见的&#xff0c;例如遇到网络波动等&#xff0c;要求某个接口或者是方法可以最多/最少调用几次&#xff1b;实现重试机制&#xff0c;非得用Retry这个重试框架吗&#xff1f;那肯定不是&#xff0c;相信…

spring-boot 依赖注入流程

一、基本使用 主要是三个注解的使用&#xff0c;Autowired&#xff0c;Value&#xff0c;Resource 二、实现步骤 拦截bean的创建 要想拦截bean&#xff0c;就需要处理spring bean生命周期事件&#xff0c;spring通过一些接口来处理事件&#xff0c;实现属性注入&#xff0c;…

python flask快速入门的10个问题

工作中需要简单写一下web服务来做一些事情&#xff0c;了解到python的flask可以快速启动。梳理一下简单的问题。 1. Flask是什么&#xff1f; Flask是一个Python Web框架&#xff0c;用于快速构建网站和Web应用程序。它是轻量级的&#xff0c;非常易于学习和使用。 2. 如何安…

学习笔记:C语言简介

静态语言&#xff1a;c语言程序设计 c语言教程 C 语言是一种通用的、面向过程式的计算机程序设计语言。&#xff08;静态语言&#xff09; #include <stdio.h> int main() //主函数,表示程序的入口,一个程序有且只能有一个main函数 {/* 我的第一个 C 程序 */printf(&quo…