4月2号网易互娱笔试2,3,4题题解

第三题意:有n个人坐电梯,电梯能承受最重w,给定n个人的重量,求怎么排列让电梯使用最多次。
样例:
输入:
6 11
1 2 4 7 9 10
输出:
5
当顺序为2 10 4 9 7 1时,需要使用5次电梯
解法:
贪心每次枚举大于w的一对(l, r)排在前面,必定要分成两次坐电梯

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main(){
    int n, w;
    scanf("%d%d", &n, &w);
    for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
    }
    sort(a, a + n);
    int l = 0, r = n - 1, ans = 0;
    while(l < r){
        if(a[l] + a[r] > w){
            ans += 2;
            l++; r--;
        }
        else{
            l++;
        }
    }
    ans += (n - ans) / 2 + (n - ans) % 2;
    printf("%d\n", ans);
}

第四题题意:有n个金蛋,每砸破一个可获得 a[left] * a[i] * a[right] 的金钱,默认a[0]和a[n + 1] 等于1.
样例:
输入:
3 1 5 8
输出:
167
3 1 5 8 --> 3 5 8 --> 3 8 --> 8
+15 +120 +24 +8 =167
dp[l][r]代表砸完区间(l,r)内所有蛋蛋只剩下两个边界l和r时获得的最大金钱,在输入的数据前面前后加入一个1记忆化搜索即可

#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int dp[N][N];
int a[N];
int dfs(int l, int r){
    if(dp[l][r] != -1)return dp[l][r];
    if(r - l == 1){
        return dp[l][r] = 0;
    }
    int ans = 0;
    for(int i = l + 1; i < r; i++){
        ans = max(ans, dfs(l, i) + dfs(i, r) + a[l] * a[i] * a[r]);
    }
    return dp[l][r] = ans;
}
char s[N * 4];
int main(){
    int n = 0, res = 0;
    a[0] = 1;
    gets(s);
    int len = strlen(s);
    for(int i = 0; i < len; i++){
        if(s[i] >= '0' && s[i] <= '9'){
            res = res * 10 + s[i] - '0';
        }
        else{
            a[++n] = res;
            res = 0;
        }
    }
    a[++n] = res;
    a[++n] = 1;
    memset(dp, -1, sizeof(dp));
    printf("%d\n", dfs(0, n));
}

第二题意:给定n个数,求三元组$(a_i,a_j,a_k)$最大公约数等于1的个数。
其中n<=99999,0 <= a[i]<=99999
样例:
输入:
8
1 2 3 4 5 6 7 8
输出:
52
如果不知道莫比乌斯反演,第二题难度感觉比前面两题加起来还要大。。。
其实莫比乌斯反演到底怎么回事,别问我,百度去。。。
最终NlogN求解

#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
bool vis[N];
int mu[N], prime[N];
//求解莫比乌斯函数
void Moblus()
{
    memset(vis, false, sizeof(vis));
    mu[1] = 1;
    int tot = 0;
    for(int i = 2; i <= N; i++){
        if(!vis[i]){
            prime[tot++] = i;
            mu[i] = -1;
        }
        for(int j = 0;j < tot; j++){
            if(i * prime[j] > N)break;
            vis[i * prime[j]] = true;
            if(i % prime[j] == 0){
                mu[i * prime[j]] = 0;
                break;
            }
            else{
                mu[i * prime[j]] = -mu[i];
            }
        }
    }
}
long long num[N], cnt[N];
int a[N];
int gcd(int x, int y){
    return x % y == 0 ? y : gcd(y, x % y);
}
//暴力检查一下结果
int check(int n){
    int res = 0;
    for(int i = 0; i < n; i++){
        for(int j = i + 1; j < n; j++){
            for(int k = j + 1; k < n; k++){
                if(gcd(a[i],gcd(a[j], a[k])) == 1)res++;
            }
        }
    }
    return res;
}
int main(){
    int n, x;
    Moblus();
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &x);
        a[i] = x;
        num[x]++;
    }
    for(int i = 1; i < N; i++){
        for(int j = i; j < N; j += i){
            cnt[i] += num[j];
        }
    }
    long long ans = 0;
    for(int i = 1; i < N; i++){
        if(cnt[i] < 3)continue;
        ans += mu[i] * cnt[i] * (cnt[i] - 1) * (cnt[i] - 2) / 6;
    }
    printf("%lld\n", ans);
    printf("%d\n", check(n));
}

黑色三月太恐怖了,腾讯简历提前批一直被锁定却从未发起面试,头条简历投了杳无音信。。。
三月只有阿里和虎牙的面试机会。。。
今天早上面完虎牙hr面,昨天刚面完阿里交叉面,写个报告攒一下RP,希望offer碗里来。

#网易互娱##题解#
全部评论
6666666
点赞 回复 分享
发布于 2019-04-07 11:11
真大佬啊!!!
点赞 回复 分享
发布于 2019-04-08 16:41

相关推荐

点赞 24 评论
分享
牛客网
牛客企业服务