百度春招笔试 系统研发工程师 题解

第一题,经典题,给一个长度为n的数字,往里面插入k个乘号,求最大可能的乘积。我用了记忆化搜索。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
unsigned long long dp[100][100];
int n, k;
int val[100];
string input;
unsigned long long getval(int lend, int rend);
unsigned long long dfs(int nn, int kk)
{       if(kk == 0)           return (dp[nn][kk] = getval(0, nn));       if(kk < 0)           return 0;
       if(dp[nn][kk] != -1)
          return dp[nn][kk];
      if(kk > nn) 
          return (dp[nn][kk] = 0);
      unsigned long long ans = 0, temp;
      for(int i = 0; i < nn; i++)//The pre multiply sign is after i-th number
      {
          temp = dfs(i, kk - 1) * getval(i + 1, nn);
            ans = max(ans, temp);
      }
      return (dp[nn][kk] = ans);
}

unsigned long long getval(int lend, int rend)//zuobi youbi
{
     unsigned long long ans = 0;
    for(int i = lend; i <= rend; i++)
    {
         ans = ans * 10;
        ans += val[i];
    }
    return ans;
}
int main(void)
{
    memset(dp, -1, sizeof(dp));
    cin >> n >> k;
    cin >> input;     for(int i = 0; i < n; i++)         val[i] = input[i] - '0';
    cout << dfs(n - 1, k) << endl;
    return 0;
}
有一些小的bug,做了大概30min。

第二题,每个节点出度只有1,求整个图最小的环的大小。因为我没有保存代码所以说一下思路。
思路就是dfs,用一个dis数组记录距离,初始化为-1;如果搜索到一个已经搜过的节点(dis[i] != -1),那么说明有环,直接减一下就可以。
这道题的麻烦之处在于可能有多个连通块,如果我们只从1号节点开始dfs,只能通过30%的数据。
那么如何处理多个连通块呢?这里一不小心,可能会只通过0%的数据,如果你这么写的话:
for(int i = 1;i <= n;i++)
    if(dis[i] == -1)
         dfs(i);
为什么呢?想象这样的情况:
1 ->2; 2 ->3; 3 ->2
如果我们之前已经搜索了2,3;这次从1开始搜索,那么2 3 这个环的大小就会被错误计算。
我的解决方案是使用并查集,每个连通块只dfs一次。我们能够保证如果每个连通块有环,那么dfs一次一定能找到对应的环。
代码因为忘了保存,希望楼下有聚聚能够贴上来qaq
#春招#
全部评论
老铁投的是什么岗位?
点赞 回复 分享
发布于 2018-04-18 21:04

相关推荐

点赞 评论 收藏
分享
评论
点赞
9
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务