8.12美团秋招第一场笔试ak攻略

T1

哈希表记录每个元素对应的位置 最后比较abs(pos[x]-pos[y])==1即可

void solve(int u){
    cin>>n;
    unordered_map<int,int>pos;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        pos[x]=i;
    }
    int x,y;
    cin>>x>>y;
    if(abs(pos[x]-pos[y])==1)puts("Yes");
    else puts("No");
}

T2

把原数组复制一份 即可破环成链 然后使用前缀和计算距离即可(注意分类讨论)

void solve(int u){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>w[i];
        w[i+n]=w[i];
    }
    for(int i=1;i<=n*2;i++){
        sum[i]=sum[i-1]+w[i];
    }
    int x,y;
    cin>>x>>y;
    x--;y--;
    if(x>y)swap(x,y);
    ll res=min(sum[y]-sum[x],sum[x+n]-sum[y]);
    cout<<res<<endl;
}

T3

二维前缀和模板题:注意只能枚举(i,m)和(n,j)的位置的终点

void solve(int u) {
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>s[i][j];
            s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
        }
    }
    ll sum=s[n][m],res=1e18;
    for(int i=1;i<=n;i++){  //枚举切割(i,m)
        ll a=s[i][m],b=sum-a;
        res=min(res,abs(a-b));
    }
    for(int i=1;i<=m;i++){ //枚举切割(n,i)
        ll a=s[n][i],b=sum-a;
        res=min(res,abs(a-b));
    }
    cout<<res<<endl;
}

T4

枚举+DFS求连通块距离

二维坐标映射到一维小技巧:n*m 二维坐标为(i,j)则一维坐标为i*m+j

记得每次开标记数组都需要重新初始化为false

void dfs(int x,int y,vector<vector<bool>>&st){ //dfs将某一个连通块全部标记
    int t=x*m+y;
    st[x][y]=true;
    for(int i=0;i<4;i++){
        int a=x+dx[i],b=y+dy[i],z=a*m+b;
        if(a<0||a>=n||b<0||b>=m||st[a][b]||s[z]!=s[t])continue;
        dfs(a,b,st);
    }
}
int f(){  //求连通块个数
    vector<vector<bool>>st(n,vector<bool>(m,false));
    int cnt=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(!st[i][j]){
                cnt++;
                dfs(i,j,st);
            }
        }
    }
    return cnt;
}
void solve(int u) {
    cin>>k;
    cin>>s;
    int res=k;
    for(int i=1;i<=k;i++){
        if(k%i){  //必须要可以整除
            continue;  
        }
        n=i;m=k/i;
        res=min(res,f());
    }
    cout<<res<<endl;
}

T5

树形dp+数论(数据好像超级弱,应该没有1e9)

check(a,b)乘积是否为完全平方数可以使用质因数分解法:看二者的质因数分解的和的每个质因数的个数是否都是偶数(复杂度logU) U<=1e9

考虑对u节点染色:(u节点和他的子节点x都会被染色)

设f[u][0]表示以u为根节点且u没被染色的最多红色节点个数

f[u][1]表示以u为根节点且u被染色的最多红色节点个数

显然f[u][0]+=max(f[x][1],f[x][0])

对于f[u][1] 只能选择某一个子节点染色 假设选择的子节点为x

f[u][1]=f[u][0]-max(f[x][0],f[x][1])+f[x][0]+2

因此可以遍历子节点 取max即可

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
#define x first
#define y second
typedef long long ll;
const int N=2E5+10,mod=1e9+7;
int T,w[N],n,res;
unordered_set<ll>st;
bool is_st[N];
vector<int>g[N];
int f[N][2];
bool check(int a,int b){
    ll c=sqrt(1ll*a*b);
    return c*c==1ll*a*b;
}
void dfs(int u,int fa){
    if(g[u].size()==1&&g[u][0]==fa)return;
    for(int &x:g[u]){
        if(x==fa)continue;
        dfs(x,u);
        f[u][0]+=max(f[x][0],f[x][1]);
        }
    for(int &x:g[u]){
        if(x==fa)continue;
        int a=w[u],b=w[x];
        if(check(a,b)){
            f[u][1]=max(f[u][1],f[u][0]-max(f[x][0],f[x][1])+2+f[x][0]);
        }
    }

    }
void solve(int u){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>w[i];
    for(int i=1;i<n;i++){
        int a,b;
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,0);
    cout<<max(f[1][0],f[1][1])<<endl;

}
int main(){
    T=1;
    for(int i=1;i<=T;i++){
        solve(i);
    }
    return 0;
}

#你的秋招第一场笔试是哪家##美团笔试##后端开发##互联网大厂秋招#
互联网笔试真题题解 文章被收录于专栏

收录近两年互联网公司笔试真题解析,并提供Java,Python,C++三种语言版本的代码

全部评论
大佬,最后一题状态转移没看懂,能细说吗
1 回复 分享
发布于 2023-08-12 12:20 浙江
第四题复杂度这么高也能过吗
1 回复 分享
发布于 2023-08-12 12:29 安徽
public class Main { static long[]w; static List<integer>[]children; public static boolean isTSN(long num) { long n = (long) Math.sqrt(num); return n * n == num; } public static int[]dfs(int cur) { if (children[cur] == null) return new int[]{0, 0}; int[]ret = new int[]{0, 0}; int bonus = 0; for (int child : children[cur]) { int[]childRes = dfs(child); boolean flag = isTSN(w[cur] * w[child]); bonus = Math.max(bonus, childRes[1] + (flag ? 2 : 0) - childRes[0]); ret[1] += childRes[0]; } ret[0] = ret[1] + bonus; return ret; } } </integer>
1 回复 分享
发布于 2023-08-12 12:51 上海
什么??!有5题?我怎么只有4题
1 回复 分享
发布于 2023-08-12 17:23 安徽
yhy 神!
点赞 回复 分享
发布于 2023-08-12 12:10 安徽
牛逼
点赞 回复 分享
发布于 2023-08-12 12:17 上海
判断完全平方数直接sqrt算一下,再看看这个结果的平方是否等于那个数,这个方法是不是也行
点赞 回复 分享
发布于 2023-08-12 12:18 河北
nbnb
点赞 回复 分享
发布于 2023-08-12 12:19 江苏
yhy,神!
点赞 回复 分享
发布于 2023-08-12 12:21 安徽
大佬,f[u][1]=f[u][0]-max(f[x][0],f[x][1])+f[x][0]+2,这里的-max(f[x][0],f[x][1])怎么理解?
点赞 回复 分享
发布于 2023-08-12 12:26 浙江
yhy 神!
点赞 回复 分享
发布于 2023-08-12 12:42 北京
贴一下我的,dfs每个节点返回一个arr arr[0]:自己可能被染的情况下,以自己为根的子树最多能染色多少个节点 arr[1]:自己一定不被染的情况下,以自己为根的子树最多能染色多少个节点 显然有个隐含条件是arr[0] >= arr[1](因为条件更宽松,所以可能染得肯定更多) 那么每个节点汇总信息的时候,自己一定不被染的情况就是各子树被染节点最多的情况的和,因为arr[0]>=arr[1],所以只加arr[0]就可以。 自己被染色,那最多只能和一个子节点一起被染,假设和子节点A一起染,最后的结果是(A[1] + 2)+ ∑(所有子节点 \ A)[0] 我们要找到子节点里能和自己构成完全平方数,且 A[1] + 2 - A[0] 最大的那个节点,遍历的时候记录最大值,最后累加到自己的[1]上就可以。即(A[1] + 2 - A[0] + ∑所有子节点[0] == A[1] + 2 + ∑(所有子节点 \ A)[0])
点赞 回复 分享
发布于 2023-08-12 12:50 上海
蜗壳,米哈游投了吗😁
点赞 回复 分享
发布于 2023-08-12 13:15 上海
第三题的一刀切原来是直接横切一刀或竖切一刀完事,我以为是要拐弯几次的那个切法。。。。
点赞 回复 分享
发布于 2023-08-12 13:56 上海
你们都在哪里刷题,我一道都不会。
点赞 回复 分享
发布于 2023-08-16 10:57 四川
请问在哪里刷的笔试题,完全不会啊
点赞 回复 分享
发布于 2023-08-19 16:18 北京

相关推荐

不愿透露姓名的神秘牛友
11-27 10:52
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
18
76
分享
牛客网
牛客企业服务