字节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 四川

相关推荐

点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
评论
3
9
分享
牛客网
牛客企业服务