网易2018校招题解与思路

缩写

分析

直接取出每个单词的首字母即可

参考代码

#include <bits/stdc++.h>

using namespace std;

char s[55];
int main() {
    gets(s);
    int len = strlen(s);
    string ans = "";
    for(int i = 0; i < len; i++) {
        if(i == 0 || s[i - 1] == ' ') ans += s[i];
    }
    cout << ans << endl;
    return 0;
}

最小众倍数

分析

注意到范围很小,直接暴力枚举check即可。

参考代码

#include <bits/stdc++.h>

using namespace std;

int a[5];
int main() {
    for(int i = 0; i < 5; i++) cin >> a[i];
    int x = 1;
    while(x) {
        int cnt = 0;
        for(int i = 0; i < 5; i++) {
            cnt += (x % a[i] == 0);
        }
        if(cnt >= 3) {
            cout << x << endl;
            return 0;
        }
        x++;
    }
    return 0;
}

数位重排

分析

暴力。
把数字的数位做一个全排列,然后check一下是否满足即可。

参考代码

#include <bits/stdc++.h>

using namespace std;

template <typename T> string tostr(const T& t) { ostringstream os; os<<t; return os.str(); } 
int t, x;
int main() {
    cin >> t;
    while(t--) {
        cin >> x;
        string s = tostr(x);
        sort(s.begin(), s.end());
        int flag = 1;
        do {
            int t = atoi(s.c_str());
            if(t != x && t % x == 0) {
                cout << "Possible" << endl;
                flag = 0;
            }
        } while(flag && next_permutation(s.begin(), s.end())); 
        if(flag) cout << "Impossible" << endl;
    }
    return 0;
}

数轴

分析

暴力。
因为步长s可能会比较大。
我们枚举一个分界点:
一种是分界点左边的整体向右移动,右边的整体向左移动。
一种是分界点左边的整体向左移动,右边的整体向右移动。
维护一个最小值即可。

参考代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100 + 5;

int n, s;
int x[maxn];
int main() {
    cin >> n >> s;
    for(int i = 0; i < n; i++) cin >> x[i];
    sort(x, x + n);
    vector<int> v;
    for(int i = 0; i < n; i++) v.push_back(x[i]);
    int ans = x[n - 1] - x[0];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j <= i; j++) {
            v[j] = x[j] + s;
        }
        for(int j = i + 1; j < n; j++) {
            v[j] = x[j] - s;
        }
        sort(v.begin(), v.end());
        ans = min(ans, v[n - 1] - v[0]);
    }
    for(int i = 0; i < n; i++) {
        for(int j = 0; j <= i; j++) {
            v[j] = x[j] - s;
        }
        for(int j = i + 1; j < n; j++) {
            v[j] = x[j] + s;
        }
        sort(v.begin(), v.end());
        ans = min(ans, v[n - 1] - v[0]);
    }
    cout << ans << endl;
}

工作方案

分析

情况有点多的一个动态规划,直接记忆化搜索就可以。
代码比较容易懂。

参考代码

#include <bits/stdc++.h>

using namespace std;

const int maxn = 50 + 5;
const int mod = 1e9 + 7;
int dp[maxn][maxn][maxn][maxn];
int solve(int s, int a, int b, int c) {
    if(s == 0) {
        if(a + b + c == 0) return 1;
        else return 0;
    }
    if(a + b + c < s) return 0;
    int &res = dp[s][a][b][c];
    if(res != -1) return res;
    res = 0;
    if(a) res = (res + solve(s - 1, a - 1, b, c)) % mod;
    if(b) res = (res + solve(s - 1, a, b - 1, c)) % mod;
    if(c) res = (res + solve(s - 1, a, b, c - 1)) % mod;
    if(a && b) res = (res + solve(s - 1, a - 1, b - 1, c)) % mod;
    if(b && c) res = (res + solve(s - 1, a, b - 1, c - 1)) % mod;
    if(c && a) res = (res + solve(s - 1, a - 1, b, c - 1)) % mod;
    if(a && b && c) res = (res + solve(s - 1, a - 1, b - 1, c - 1)) % mod;
    return res; 
}
int main() {
    int s, a, b, c;
    cin >> s >> a >> b >> c;
    memset(dp, -1, sizeof(dp));
    cout << solve(s, a, b, c) << endl;
    return 0;
}

骰子游戏

分析

直接动态规划算出所有满足的情况数。
总情况数是6^n
最后做一个约分即可,注意答案需要64位整数来存。

参考代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
ll dp[25][150];
ll quick_pow(ll a, ll b) {
    ll res = 1;
    while(b) {
        if(b & 1) res *= a;
        a *= a;
        b >>= 1;
    }
    return res;
}
int main() {
    int n, x;
    cin >> n >> x;
    memset(dp, 0, sizeof(dp));
    for(int i = 1; i <= 6; i++) dp[1][i] = 1;
    for(int i = 1; i < n; i++) {
        for(int j = 1; j <= 150; j++) {
            if(!dp[i][j]) continue;
            for(int k = 1; k <= 6; k++) {
                dp[i + 1][j + k] += dp[i][j];
            }
        }
    }
    ll all = quick_pow(6, n);
    ll sum = 0;
    for(int i = x; i <= 150; i++) sum += dp[n][i];
    if(sum == all) printf("1\n");
    else if(sum == 0) printf("0\n");
    else {
        ll g = __gcd(sum, all);
        printf("%lld/%lld\n", (sum / g), (all / g));
    }
    return 0;
}
#网易#
全部评论
数位重排不用暴力枚举组合的,说了是该数的倍数。肯定是10倍以内,然后挨个匹配就行了。
点赞 回复 分享
发布于 2017-09-25 17:21
using System; using System.Collections.Generic; class Program {     static void Main(string[] args)     {         string str;         str = Console.ReadLine();         var t = int.Parse(str);         List<int> nums = new List<int>(t);         for (var i = 0; i < t; ++i)         {             str = Console.ReadLine();             nums.Add(int.Parse(str));         }         nums.ForEach(n =>         {             char[] ss = n.ToString().ToCharArray();             List<int> result = new List<int>();             GetAllRange(ref ss, 0, ref result);             bool possible = false;                 //Console.WriteLine(result.Count);                 foreach (var i in result)             {                     //Console.WriteLine($"{i} mod {n} = {i % n}");                     if (i != n && i % n == 0)                 {                     possible = true;                     break;                 }             };             if (possible)             {                 Console.WriteLine("Possible");             }             else             {                 Console.WriteLine("Impossible");             }         });         Console.ReadKey();     }     static void GetAllRange(ref char[] ss, int k, ref List<int> result)     {         if (k == ss.Length)         {             string s = new string(ss);             result.Add(int.Parse(s));         }         else         {             for (int i = k; i < ss.Length; i++)             {                 Swap(ref ss, k, i);                 GetAllRange(ref ss, k + 1, ref result);                 Swap(ref ss, k, i);             }         }     }     static void Swap(ref char[] ss, int k, int i)     {         char temp = ss[k];         ss[k] = ss[i];         ss[i] = temp;     } } 第一题通过率倒是100%
点赞 回复 分享
发布于 2017-09-25 17:32
我穿越了?
点赞 回复 分享
发布于 2017-09-25 22:15
有没有题目分享
点赞 回复 分享
发布于 2017-09-26 09:47
高。。。实在是高
点赞 回复 分享
发布于 2017-09-25 17:05
膝盖跪软了
点赞 回复 分享
发布于 2017-09-25 17:07
在下真的服了
点赞 回复 分享
发布于 2017-09-25 17:08
不由想起一句话:你是畜生吗?(没有吗你的意思,只是服的不行不行了)
点赞 回复 分享
发布于 2017-09-25 17:14
工作方案那题  到最后十几分钟才意识到解题思路 已经来不及了  哭泣
点赞 回复 分享
发布于 2017-09-25 17:14
代码简单到看不懂.............
点赞 回复 分享
发布于 2017-09-25 17:16
数位重排还有一个更加简单的方法: 对当前数字乘以2-9之间的倍数且取所得数字中 位数和当前数字相同的几个 看每一个所得数的组成(set)是否和当前数相同,如(1035->1,0,3,5和3015->3,0,1,5)的两个set其实是相同的
点赞 回复 分享
发布于 2017-09-25 17:16
这次笔试的编程总共有2套题么,我怎么觉得前三个比后三个相对的简单?你们做的都是前三个还是后三个?
点赞 回复 分享
发布于 2017-09-25 17:18
非常后悔没有看下一道题,没有好好把握时间T T
点赞 回复 分享
发布于 2017-09-25 17:20
一人血书,建议楼主直接拿走off……
点赞 回复 分享
发布于 2017-09-25 17:20
using System; using System.Collections.Generic; class Program {     static void Main(string[] args)     {         string str;         str = Console.ReadLine();         string[] ss = str.Split(' ');         int n = int.Parse(ss[0]);         int x = int.Parse(ss[1]);         List<List<int>> result = new List<List<int>>();         Dictionary<int, int> state = new Dictionary<int, int>();         GetAllPossible(n, n, x, ref state, ref result);         int possibles = 0;         int all = Convert.ToInt32(Math.Pow(6, n));         for (int i = 0; i < result.Count; i++)         {             int sum = 0;             result[i].ForEach(t =>             {                 //Console.Write($"{t} ");                 sum += t;             });             //Console.WriteLine($"sum={sum}");             if (sum > x)             {                 possibles++;             }         }         int g = GCD(all, possibles);         Console.WriteLine($"{possibles / g}/{all / g}");         Console.ReadKey();     }     static int GCD(int a, int b)     {         int i;         for (i = a; i > 0; i--)         {             if ((a % i == 0) && (b % i == 0)) break;         }         return i;     }     static void GetAllPossible(int n, int k, int x, ref Dictionary<int, int> state, ref List<List<int>> result)     {         k--;         //n为骰子数量         //k为当前骰子序号         //i为当前骰子点数         if (k >= 0)         {             for (int i = 1; i <= 6; i++)             {                 state[k] = i;                 //Console.WriteLine($"第{n + 1}个骰子点数:{i}");                 //Console.WriteLine($"state[{k}]={state[k]}");                 if (k == 0)//结束一次深入                 {                     List<int> r = new List<int>();                     for (int j = 0; j < n; j++)                     {                         r.Add(state[j]);                     }                     result.Add(r);                 }                 GetAllPossible(n, k, x, ref state, ref result);             }         }     } } 第3题时间过了才完成,不知道对不对。。
点赞 回复 分享
发布于 2017-09-25 17:29
数轴的那个为啥要考虑左边的往左右边的往右啊,最小的情况不都应该是左边的往右右边的往左吗
点赞 回复 分享
发布于 2017-09-25 17:33
数轴那题, 算出所有的点+id, 可以搞个滑动窗口来做吧
点赞 回复 分享
发布于 2017-09-25 17:33
数轴那题,分界点左侧向左移动,右侧向右移动是在什么情况下? 我做的时候,先排序,再取分界点mid = (max+min)/2,如果小于等于分界点,则右移,大于分界点,则左移,再从新的数据中求max和min,得到结果res = max-min。但通过率只有60%。求大神解答。
点赞 回复 分享
发布于 2017-09-25 17:37
import java.math.BigDecimal; import java.util.Arrays; import java.util.Scanner; public class Demo2 {     public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         while(true){             int n = sc.nextInt();             int s = sc.nextInt();             System.out.println(fun(n, s));         }     }     private static String fun(int n, int s) {         if (s <= n)             return "1";         if (s > 6 * n)             return "0";         long[][] dp = new long[n][s + 1];         for (int i = 0; i < dp[0].length; i++) {             if (i >= 1 && i <= 6)                 dp[0][i] = 1;         }         for (int i = 1; i < dp.length; i++) {             for (int j = 0; j < dp[0].length; j++) {                 for (int mm = 1; j - mm > 0&&mm<=6; mm++) {                     dp[i][j] += dp[i - 1][j - mm];                 }             }         }         for (int i = 0; i < dp.length; i++) {             System.out.println(Arrays.toString(dp[i]));         }                  BigDecimal aa = new BigDecimal(0);         for (int i = 0; i < dp[0].length-1; i++) {             aa = aa.add(new BigDecimal(dp[n-1][i]));         }         BigDecimal bb = new BigDecimal(6);         BigDecimal pow = bb.pow(n);                  aa = pow.subtract(aa);         BigDecimal gcd = gcd(pow, aa);         return aa.divide(gcd).toString()+"/"+pow.divide(gcd).toString();     }     public static BigDecimal gcd(BigDecimal aa, BigDecimal bb) {          if (bb.toString().equals("0"))             return aa ;         else{             BigDecimal[] divideAndRemainder = aa.divideAndRemainder(bb);             return gcd(bb, divideAndRemainder[1]);         }     } } //被bigdecimal搞惨了
点赞 回复 分享
发布于 2017-09-25 17:46
服了
点赞 回复 分享
发布于 2017-09-25 17:53

相关推荐

一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
7 60 评论
分享
牛客网
牛客企业服务