字节8月21日 笔试第2题走迷宫,第4题 摇骰子比大小

第二题用了dfs(好像用bfs会更简洁)
#include<vector>
using namespace std;
// #include<algorithm>
#include<iostream> 

// write your code in C++ (C++14 (g++ 6.2.0))

int ans = 1;
bool dfs(vector<vector<char>> &maze, vector<vector<int>> &visited, int i, int j, int m, int n) {
    if(i<0 || i>=m || j<0 || j>=n) {    //碰到边
        return 0;   
    }
    if(maze[i][j] == 'O') {      
        return 1;
    }
    if(maze[i][j] == 'N') {             //碰到走不通的路
        return 0;
    }

    if(visited[i][j] == 1) return 0;    //已经走过的路
    if(visited[i][j] == 2) return 0;    //传送带
            
    bool res;
    switch(maze[i][j]){
        case '.':
        visited[i][j] = 1;
        res = dfs(maze, visited, i+1, j, m, n) || dfs(maze, visited, i-1, j, m, n)
        || dfs(maze, visited, i, j+1, m, n) || dfs(maze, visited, i, j-1, m, n);
        break;
     
        case 'R':
        visited[i][j] = 2;
        res = dfs(maze, visited, i, j+1, m, n);
        break;

        case 'L':
        visited[i][j] = 2;
        res = dfs(maze, visited, i, j-1, m, n);
        break;

        case 'U':
        visited[i][j] = 2;
        res = dfs(maze, visited, i-1, j, m, n);
        break;

        case 'D':
        visited[i][j] = 2;
        res = dfs(maze, visited, i+1, j, m, n);
        break;

        default:
        res = 0;
        break;
    }        
    
    if(res){                     //走的通的路标记为‘O’
        maze[i][j] = 'O';
        ans++;
        visited[i][j] = 0;
        cout<<i<<"\t"<<j<<"\t"<<int(res)<<"\t"<<ans<<endl;
        return 1;
    }else if(visited[i][j]==2){  //走不通的路标记为‘N’,                          
        maze[i][j] = 'N';        //res==0的时候如果是在‘.’上不能判定走不通,因为实际情况可以往回走  
        // visited[i][j] = 0;     
        return 0;
    }else{
        visited[i][j] = 0;
        return 0;
    }

}

int main(){
    //输入操作略
    // int m, n;
    // cin>>m>>n;
    // vector<vector<int>> maze(m,n);

    //测试用例
    int m = 5, n = 5;
    vector<vector<char>> maze = {{'.', '.', '.', '.', '.'},
                                 {'.', 'R', 'R', 'D', '.'},
                                 {'.', 'U', '.', 'D', 'R'},
                                 {'.', 'U', 'L', 'L', '.'},
                                 {'.', '.', '.', '.', 'O'}};
    // int m = 3, n = 4;
    // vector<vector<char>> maze = {{'O', 'U', '.', '.'},
    //                              {'L', '.', '.', '.'},                           
    //                              {'.', '.', '.', '.'}};

    // maze[m-1][n-1] = 'O';
    vector<vector<int>> visited(m, vector<int>(n,0));
    for(int i=0; i<m; i++){
        for(int j=0; j<n; j++){
            if(maze[i][j] != 'O' && maze[i][j]!='N'){     
                dfs(maze, visited, i, j, m, n);
            }           
        }
    }

    cout << m*n-ans<< endl;
    return 0;
}


第4题大致思路:用an,bn表示两个数组大小,suma,sumb表示数组中所有元素总和,如果摇骰子每次为结果都是1,那么结果就是数组大小,如果每次都是最大值,那么结果就是数组所有元素总和。
对于每个骰子,每一个面朝上概率是一样的,这意味着每个人的每个结果点数和的概率都是一样的,所以只要统计每组数所有可能的总和的个数就可以最后算出概率,
例如如果a  = {8}, 那么可能有8种和即1~8,每种和只有一种情况,b = {2, 3, 4},就可能有2+3+4 -3+1= 7种和(最小为3对应每个骰子恰好都是1朝上,最大是9对应每个骰子都恰好是最大值朝上)每种和对应的情况数可能不同,比如和为4的情况有3种,分别是[1, 1, 2], [1, 2, 1], [1, 1, 2],需要用dfs统计每个和的情况次数 。
ps:因为要算a组数赢的概率,所以最后比较的是a的所有情况总和中大于b的情况,这里就有剪枝的空间了: 如果 a的个数都比b的总和要大了那肯定赢,返回1.0,反之肯定输,返回0.0。
相应的,用dfs计数的时候也只需要统计最后需要比较的情况,所以dfs也可以剪枝,这里懒得写了。。。
#include<vector>
using namespace std;
#include<algorithm>
#include<iostream>
#include<unordered_map>
#include<iomanip>   

// write your code in C++ (C++14 (g++ 6.2.0))
//dfs计算掷完一组骰子每个值可能出现的次数
void dfs(vector<int> &A, unordered_map<int, int> &hashm, int cursum, int n, int depth) {
    if(depth == n) {
        hashm[cursum]++;
        return ;
    }
    for(int i=1; i<=A[depth]; i++){
        cursum += i;       
        // cout<<cursum<<":"<<hashm[cursum]<<"\t";
        dfs(A, hashm, cursum, n, depth+1);
        cursum -= i;
    }
}

int main(){
    // int an, bn;
    // cin>>an>>bn;
    // vector<int> A(an), B(bn);

    int an = 1, bn = 3;
    vector<int> A = {8}, B = {2, 3, 4};

    int suma = 0, sumb = 0;
    double p_a = 1.0, p_b = 1.0;
    for(int i=0; i<an; i++) {
        // cin>>A[i];
        suma+=A[i];
        p_a *= 1.0/A[i];
    }
    for(int i=0; i<bn; i++){
        // cin>>B[i];
        sumb+=B[i];
        p_b *= 1.0/B[i];
    } 
    if(suma<=bn){
        cout << setprecision(3) << fixed << 0.0<< endl; //控制小数位输出
        return 0;
    }
    if(sumb<an){
        cout << setprecision(3) << fixed << 1.0<< endl; //控制小数位输出
        return 0;
    }

    unordered_map<int, int> hash_a;
    unordered_map<int, int> hash_b;
    dfs(A, hash_a, 0, an, 0);
    dfs(B, hash_b, 0, bn, 0);
    int start, end;
    if(bn>an) start = bn+1;
    else start = an;
    end = suma;
    // cout<<endl;
    // cout<<an<<"\t"<<suma<<"\n"<<bn<<"\t"<<sumb<<endl;
    // cout<<"p:"<<p_a<<"\t"<<p_b<<endl;
    // cout<<"start:"<<start<<"\t"<<end<<endl;
    double ans = 0.0;
    for(int i=start; i<=end; i++){
        for(int j=bn; j<i; j++){
            ans += hash_a[i]*p_a*hash_b[j]*p_b;
            // cout<<i<<":"<<hash_a[i]<<"\t"<<j<<":"<<hash_b[j]<<endl;
        }
        // cout<<ans<<endl;
    }   
    cout << setprecision(3) << fixed << ans<< endl;
}


#字节跳动##字节23秋招笔试太难了吧##原来字节劝退的只是我,罢了罢了#
全部评论
楼主厉害!学习了
点赞 回复 分享
发布于 2022-08-22 10:00 江苏
老兄投的啥岗位?有兴趣的话可以看一下荣耀,我可以内推。荣耀honor招聘官网https://www.hihonor.com/cn/career/ 内推码:yuhvad
点赞 回复 分享
发布于 2022-08-22 11:18 广东
我用dp做的摇骰子
点赞 回复 分享
发布于 2022-08-22 15:12 四川

相关推荐

10-05 11:11
海南大学 Java
投票
理想江南137:感觉挺真诚的 感觉可以试一试
点赞 评论 收藏
分享
评论
3
9
分享
牛客网
牛客企业服务