8月2日网易笔试8道编程题代码

第一题:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

//mx[i][j]表示前i个人选了j个人并且以第i个人为结尾满足相邻位置差不大于d的最大值
//mn[i][j]表示前i个人选了j个人并且以第i个人为结尾满足相邻位置差不大于d的最小值
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 110;
const long long inf = 1e16;
long long a[N], mx[N][15], mn[N][15];
int main(){
    int n;
    while(scanf("%d", &n) > 0){
        for(int i = 1; i <= n; i++){
            scanf("%lld", &a[i]);
        }
        int d, m;
        scanf("%d%d", &m, &d);
        for(int i = 1; i <= n; i++){
            mx[i][0] = 1;
            mn[i][0] = 1;
            for(int j = 1; j <= m; j++){
                mx[i][j] = -inf;
                mn[i][j] = inf;
            }
        }
        long long mmx = -100, mmn = 100;
        long long ans = -inf;
        for(int i = 1; i <= n; i++){
                mmx = max(mmx, a[i]);
                mx[i][1] = a[i];
                mn[i][1] = a[i];
                if(m == 1)ans = max(ans, mmx);
        }
        for(int i = 1; i <= n; i++){
            for(int j = 2; j <= m && j <= i; j++){
                for(int k = i - 1; k >= max(1, i - d) && k >= j - 1; k--){
                    mx[i][j] = max(mx[i][j], mx[k][j - 1] * a[i]);
                    mx[i][j] = max(mx[i][j], mn[k][j - 1] * a[i]);
                    mn[i][j] = min(mn[i][j], mn[k][j - 1] * a[i]);
                    mn[i][j] = min(mn[i][j], mx[k][j - 1] * a[i]);
                    if(j == m)ans = max(ans, mx[i][j]);
                }
            }
        }
        printf("%lld\n", ans);
    }
}

第二题:给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。

//直接从起点开始bfs一遍,到达所有点的最大值即答案
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 110;
int n, m, k, x, y;
char s[N][N];
int dx[N], dy[N], vis[N][N];
struct node{
    int x, y, step;
    node(){}
    node(int x, int y, int step):x(x), y(y), step(step){}
};
bool inside(int i, int j){
    return i >= 0 && i < n && j >= 0 && j < m;
}
void bfs(){
    memset(vis, 0, sizeof vis);
    queue<node>que;
    que.push(node(x, y, 0));
    vis[x][y] = 1;
    int ans = -1;
    while(!que.empty()){
        node now = que.front();
        que.pop();
        for(int i = 0; i < k; i++){
            int nx = now.x + dx[i];
            int ny = now.y + dy[i];
            if(!inside(nx, ny))continue;
            if(s[nx][ny] == 'X' || vis[nx][ny])continue;
            //printf("%d %d\n", nx, ny);
            vis[nx][ny] = 1;
            que.push(node(nx, ny, now.step + 1));
            ans = max(ans, now.step + 1);
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(!vis[i][j] && s[i][j] == '.')ans = -1;
        }
    }
    printf("%d\n", ans);
}
int main(){
    while(scanf("%d%d", &n, &m) > 0){
        for(int i = 0; i < n; i++){
            scanf("%s", s[i]);
        }
        scanf("%d%d", &x, &y);
        scanf("%d", &k);
        for(int i = 0; i < k; i++){
            scanf("%d%d", &dx[i], &dy[i]);
        }
        bfs();
    }
}

第三题:牛牛想尝试一些新的料理,每个料理需要一些不同的材料,问完成所有的料理需要准备多少种不同的材料。

#include <cstdio>
#include <iostream>
#include <set>
#include <string>
using namespace std;
set<string>st;
int main(){
    string s;
    while(cin >> s){
        st.insert(s);
    }
    printf("%d\n", st.size());
}

第四题:牛牛和 15 个朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成 16 份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地, 作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗?

//二分答案,判断可行性时暴力枚举三列的情况,然后横着贪心地扫一遍,每当四个都满足时就砍一刀,满足四次即可,复杂度O(N^4logN)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 10010;
char str[100];
int a[110][110];
int sum[110][110], n, m;
int calc(int x, int y, int i, int j){
    return sum[x][y] - sum[x][j] - sum[i][y] + sum[i][j];
}
bool judge(int x){
   for(int i = 1; i <= m - 3; i++)
   {
       for(int j = i + 1; j <= m - 2; j++)
       {
           for(int k = j + 1; k <= m - 1; k++)
           {
                int last = 0, cnt = 0;
                for(int r = 1; r <= n; r++){
                    int s1 = calc(r, i, last, 0);
                    int s2 = calc(r, j, last, i);
                    int s3 = calc(r, k, last, j);
                    int s4 = calc(r, m, last, k);
                    if(s1 >= x && s2 >= x && s3 >= x && s4 >= x){
                        last = r; cnt++;
                    }
                  //  printf("i = %d j = %d k = %d last = %d\n",i, j, k, last);
                }
                if(cnt >= 4)return true;
           }
       }
   }
   return false;
}
int main(){
    while(scanf("%d%d", &n, &m) > 0){
        for(int i = 1; i <= n; i++){
            scanf("%s", str + 1);
            for(int j = 1; j <= m; j++){
                a[i][j] = str[j] - '0';
            }
        }
        memset(sum, 0, sizeof sum);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
            }
        }
        int l = 0, r = sum[n][m], ans = 0;
        while(l <= r){
            int m = (l + r) >> 1;
            if(judge(m)){
                l = m + 1;
                ans = m;
            }
            else r = m - 1;
        }
        printf("%d\n", ans);
    }
}

第五题:n 只奶牛坐在一排,每个奶牛拥有 ai 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果,如果方案不存在输出 -1。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[110];
int main(){
    int n;
    while(scanf("%d", &n) > 0){
        int sum = 0;
        for(int i = 1; i <= n ; i++){
            scanf("%d", &a[i]);
            sum += a[i];
        }
        int flag = 0;
        if(sum % n != 0)flag = 1;
        int avg = sum / n, cnt = 0;
        for(int i = 1; i <= n; i++){
            if(abs(a[i] - avg) % 2 != 0)flag = 1;
            cnt += abs(a[i] - avg) / 2;
        }
        if(flag)puts("-1");
        else printf("%d\n", cnt / 2);
    }
}

第六题:航天飞行器是一项复杂而又精密的仪器,飞行器的损耗主要集中在发射和降落的过程,科学家根据实验数据估计,如果在发射过程中,产生了 x 程度的损耗,那么在降落的过程中就会产生 x2 程度的损耗,如果飞船的总损耗超过了它的耐久度,飞行器就会爆炸坠毁。问一艘耐久度为 h 的飞行器,假设在飞行过程中不产生损耗,那么为了保证其可以安全的到达目的地,只考虑整数解,至多发射过程中可以承受多少程度的损耗?

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[110];
int main(){
    long long n;
    while(scanf("%lld", &n) > 0){
        long long l = 0, r = sqrt(n * 1.0), ans = 0;
        while(l <= r){
            long long m = (l + r) >> 1;
            if(m * m + m <= n){
                l = m + 1;
                ans = m;
            }
            else r = m - 1;
        }
        cout << ans << endl;
    }
}

第七题:牛牛拿到了一个藏宝图,顺着藏宝图的指示,牛牛发现了一个藏宝盒,藏宝盒上有一个机关,机关每次会显示两个字符串 s 和 t,根据古老的传说,牛牛需要每次都回答 t 是否是 s 的子序列。注意,子序列不要求在原字符串中是连续的,例如串 abc,它的子序列就有 {空串, a, b, c, ab, ac, bc, abc} 8 种。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main(){
    char s1[20], s2[20];
    while(scanf("%s%s", s1, s2) > 0){
        int i = 0, j = 0;
        int len1 = strlen(s1), len2 = strlen(s2);
        while(i < len1 && j < len2){
            if(s1[i] == s2[j]){
                i++; j++;
            }
            else i++;
        }
        if(j == len2)puts("Yes");
        else puts("No");
    }
}

第八题:牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。

//因为看不清的位置至多只有10个,直接暴力全排列所有的可能性去判断即可,计算顺序对时可用树状数组O(NlogN)优化一下,不过暴力O(N^2)也能过,都暴力好了。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int a[N], b[N], vis[N];
int c[15];
bool judge(int n, int k, int b[]){
    int ret = 0;
    for(int i = 1; i <= n; i++){
        for(int j = i + 1; j <= n; j++){
            if(b[i] < b[j])ret++;
        }
    }
    //printf("%d %d\n", ret, k);
    return ret == k;
}
int main(){
    int n, k;
    while(scanf("%d%d", &n, &k) > 0){
        memset(vis, 0, sizeof vis);
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            vis[a[i]] = 1;
        }
        int tot = 0;
        for(int i = 1; i <= n; i++){
            if(!vis[i])c[tot++] = i;
        }
        int index[15] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int ans = 0;
        do{
            int idx = 0;
            for(int i = 1; i <= n; i++){
                if(a[i] == 0)b[i] = c[index[idx++]];
                else b[i] = a[i];
             //   printf("%d ", b[i]);
            }
           // puts("");
            if(judge(n, k, b))ans++;
        }while(next_permutation(index, index + tot));
        printf("%d\n", ans);
    }
}
全部评论
好厉害!赞赞赞
点赞 回复 分享
发布于 2016-08-07 10:29
第三题 程序怎么结束呀?程序结束不了呀
点赞 回复 分享
发布于 2016-08-07 15:57
有java实现的答案吗
点赞 回复 分享
发布于 2016-08-10 16:50
分田那道题while(l <= r){ int m = (l + r) >> 1; if(judge(m)){ l = m + 1; ans = m; } else r = m - 1; }这个位置m被重新定义了,(l+r)>>1是什么意思?楼主能够解释以下吗?
点赞 回复 分享
发布于 2016-08-11 16:22
感谢楼主分享………………
点赞 回复 分享
发布于 2016-08-12 18:34
好棒
点赞 回复 分享
发布于 2016-08-17 16:13
LZ,你在OJ里获得Ac了吗?
点赞 回复 分享
发布于 2016-08-17 16:38
楼楼,分田地那题怎么想到用二分的呀
点赞 回复 分享
发布于 2016-09-06 19:42
请问分田那个sum【】【】是什么意思,能再稍微具体解释下吗?非常感谢~
点赞 回复 分享
发布于 2017-04-09 22:34
头条内推码4EXU9YH 投递链接:https://job.toutiao.com/campus/
点赞 回复 分享
发布于 2017-09-08 22:16
请问有python实现的吗?
点赞 回复 分享
发布于 2017-10-12 01:59

相关推荐

昨天 13:52
门头沟学院 后端
给🐭🐭个面试机会吧:嘿,mvbatis
点赞 评论 收藏
分享
评论
26
129
分享

创作者周榜

更多
牛客网
牛客企业服务