网易笔试20220317题解

第一题 锯齿数独
判读该数独能否填完。
如果有多种填法就输出Multiple;
如果有一种就输出Unique并输出该种填法;
如果不能填完就输出No。

暴力回溯,注意每一行每一列也要满足数独要求。

#include <bits/stdc++.h>
using namespace std;

struct Node {
    int x, y;
};

// int ans;
vector<string> ans_grid;
set<vector<string>>ans;//记录所有解法,set用来去重

bool check(vector<string> &grid, vector<vector<Node>> &pos) {
    
    //判断每个锯齿是否满足数独要求
    for(int i = 0; i < 3; i++) {
        vector<int>count(3);
        for(int j = 0; j < 3; j++) {
            if(isdigit(grid[pos[i][j].x][pos[i][j].y])) count[grid[pos[i][j].x][pos[i][j].y] - '1']++;
        }
        if(count[0] != 1 || count[1] != 1 || count[2] != 1) return false;
    }

    //判断每行是否满足数独要求
    for(int i = 0; i < 3; i++) {
        vector<int>count(3);
        for(int j = 0; j < 3; j++) {
            if(isdigit(grid[i][j])) count[grid[i][j] - '1']++;
        }
        if(count[0] != 1 || count[1] != 1 || count[2] != 1) return false;
    }

    //判断每列是否满足数独要求
    for(int i = 0; i < 3; i++) {
        vector<int>count(3);
        for(int j = 0; j < 3; j++) {
            if(isdigit(grid[j][i])) count[grid[j][i] - '1']++;
        }
        if(count[0] != 1 || count[1] != 1 || count[2] != 1) return false;
    }


    // for(auto &i: grid) cout << i << endl;
    //     cout << endl;
    return true;
}

void dfs(vector<string> &grid, vector<vector<Node>> &pos) {
    int x = -1, y = -1;
    //寻找下一个*,找不到x就等于-1
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            if(grid[i][j] == '*') {
                x = i, y = j;
                break;
            }
        }
        if(x != -1) break;
    }
    // cout << x << " " << y << endl;
    // cout << endl;
    if(x != -1) {//还有*没填
        grid[x][y] = '1';
        dfs(grid, pos);
        grid[x][y] = '2';
        dfs(grid, pos);
        grid[x][y] = '3';
        dfs(grid, pos);
        grid[x][y] = '*';
    } else {
        if(check(grid, pos)) {//填完了就检查是否满足要求
            ans.insert(grid);
            ans_grid = grid;
        }
    }
}

int main() {

    int T;
    cin >> T;
    while(T--) {
        vector<string>grid(3);
        for(int i = 0; i < 3; i++) cin >> grid[i];
        vector<vector<Node>>pos(3, vector<Node>(3));//记录三个锯齿
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                cin >> pos[i][j].x >> pos[i][j].y;
            }
        }
        // ans = 0;
        ans.clear();
        dfs(grid, pos, 0, 0);
        if(ans.size() == 1) {
            cout << "Unique" << endl;
            for(int i = 0; i < 3; i++) cout << ans_grid[i] << endl;
        } else if(ans.size() == 0) {
            cout << "No" << endl;
        } else {
            cout << "Multiple" << endl;
        }
    }


    return 0;
}


第二题 黑白棋

黑白轮流下,每次判断八个方位中最远的异色棋位置,然后把中间的棋子颜色反转,并且一个棋子不能被连续两轮反转颜色

直接模拟,注意只考虑连续的棋子,即中间不能有空位!!

#include <bits/stdc++.h>
using namespace std;

int dir[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};


int main() {

    int T;
    cin >> T;
    while(T--) {
        int n, m;
        cin >> n >> m;
        vector<string>s(n);
        for(int i = 0; i < n; i++) cin >> s[i];
        vector<vector<bool>>last(n, vector<bool>(n, false));//记录上一轮哪些棋子动过
        char now = 'w';
        for(int i = 0; i < m; i++) {
            int x, y;
            cin >> x >> y;
            // cout << endl;
            vector<vector<bool>>current(n, vector<bool>(n, false));//记录当前哪些棋子动过
            s[x][y] = now;
            // current[x][y] = true;
            for(int k = 0; k < 8; k++) {
                int far_x = -1, far_y = -1;
                int cur_x = x + dir[k][0], cur_y = y + dir[k][1];
                while(cur_x >= 0 && cur_x < n && cur_y >= 0 && cur_y < n) {//找到最远的异色棋子位置
                    if(s[cur_x][cur_y] == '-') break;//注意中间不能有空位!!
                    if(s[cur_x][cur_y] != now) {
                        far_x = cur_x;
                        far_y = cur_y;
                    }
                    cur_x += dir[k][0];
                    cur_y += dir[k][1];
                }
                if(far_x != -1) {//没有异色棋子
                    // cout << far_x << far_y << endl;
                    cur_x = x + dir[k][0];
                    cur_y = y + dir[k][1];
                    while(cur_x >= 0 && cur_x < n && cur_y >= 0 && cur_y < n) {
                        if(cur_x == far_x && cur_y == far_y) break;
                        if(!last[cur_x][cur_y]) {//如果上一轮没有动过颜色,就反转颜色
                            if(s[cur_x][cur_y] != '-') {
                                last[cur_x][cur_y] = true;
                                current[cur_x][cur_y] = true;
                                if(s[cur_x][cur_y] == 'w') s[cur_x][cur_y] = 'b';
                                else if(s[cur_x][cur_y] == 'b') s[cur_x][cur_y] = 'w';
                            }
                        }
                        cur_x += dir[k][0];
                        cur_y += dir[k][1];
                    }
                }
            }
            last = current;
            if(now == 'w') now = 'b';
            else now = 'w';
            for(int i = 0; i < n; i++) cout << s[i] << endl;
            cout << endl << endl;
        }
        for(int i = 0; i < n; i++) cout << s[i] << endl;
        cout << "END" << endl;

    }

    return 0;
}


第三题 消灭敌人

给定地图有a个人消灭b个敌人,第i个人每次可以走v[i]步,不能穿过墙和敌人,除非最后一步是敌人(最后一步是敌人就消灭)。求消灭所有敌人最短步数。

还是准备暴力搜索,结果超时,无解

#include <bits/stdc++.h>
using namespace std;

int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

struct Node {
    int x, y, step;
    Node() {
        step = 0;
    }
};

int ans;
bool vis[11][21][21];
int n, m, a, b;

void dfs(vector<string> &s, vector<int> &v, int b, int step, vector<Node> &person, int index) {
    if(b == 0) {
        ans = min(ans, step);
        return;
    }
    if(step >= ans) return;
    if(index != -1) {
        int i = index;
        for(int k = 0; k < 4; k++) {
            int next_x = person[i].x + dir[k][0];
            int next_y = person[i].y + dir[k][1];
            if(next_x >= 0 && next_x < n && next_y >= 0 && next_y < m && s[next_x][next_y] != 'W' && !vis[i][next_x][next_y]) {
                vis[i][next_x][next_y] = true;
                int pre_x = person[i].x;
                int pre_y = person[i].y;
                person[i].x = next_x;
                person[i].y = next_y;
                person[i].step++;

                int next_b = b;
                if(s[next_x][next_y] == 'E' && person[i].step % v[i] == 0) {
                    next_b--;
                    s[next_x][next_y] = '+';
                }
                if(person[i].step % v[i] == 0) {
                    dfs(s, v, next_b, step + 1, person, -1);
                } else {
                    dfs(s, v, next_b, step + 1, person, index);
                }

                person[i].step--;

                if(next_b != b) {
                    s[next_x][next_y] = 'E';
                }
                person[i].x = pre_x;
                person[i].y = pre_y;
                vis[i][next_x][next_y] = false;
            }
        }
    }
    for(int i = 0; i < a; i++) {
        for(int k = 0; k < 4; k++) {
            int next_x = person[i].x + dir[k][0];
            int next_y = person[i].y + dir[k][1];
            if(next_x >= 0 && next_x < n && next_y >= 0 && next_y < m && s[next_x][next_y] != 'W' && !vis[i][next_x][next_y]) {
                vis[i][next_x][next_y] = true;
                int pre_x = person[i].x;
                int pre_y = person[i].y;
                person[i].x = next_x;
                person[i].y = next_y;
                person[i].step++;

                int next_b = b;
                if(s[next_x][next_y] == 'E' && person[i].step % v[i] == 0) {
                    next_b--;
                    s[next_x][next_y] = '+';
                }
                if(person[i].step % v[i] == 0) {
                    dfs(s, v, next_b, step + 1, person, -1);
                } else {
                    dfs(s, v, next_b, step + 1, person, i);
                }
                person[i].step--;

                if(next_b != b) {
                    s[next_x][next_y] = 'E';
                }
                person[i].x = pre_x;
                person[i].y = pre_y;
                vis[i][next_x][next_y] = false;
            }
        }
    }
}

int main() {

    int T;
    cin >> T;
    while(T--) {
        cin >> n >> m >> a >> b;
        vector<int>v(a);
        for(int i = 0; i < a; i++) {
            cin >> v[i];
        }
        vector<string>s(n);
        vector<Node>person(a);
        memset(vis, false, sizeof(vis));

        for(int i = 0; i < n; i++) {
            cin >> s[i];
            for(int j = 0; j < s[i].size(); j++) {
                if(isdigit(s[i][j])) {
                    person[s[i][j] - '0'].x = i;
                    person[s[i][j] - '0'].y = j;
                    vis[s[i][j] - '0'][i][j] = true;
                }
            }
        }
        ans = INT_MAX;
        dfs(s, v, b, 0, person, -1);
        if(ans == INT_MAX) cout << -1 << endl;
        else cout << ans << endl;
    }

    return 0;
}

/*

2
1 10 1 1
4
0++++E++++
4 4 2 2
4 4
0++1
EWW+
+WW+
+E++
*/




#网易笔试##笔经##网易#
全部评论
第三题应该是多源bfs,复杂度是n*m*4的那种
点赞 回复 分享
发布于 2022-03-25 10:27
这代码量怎么都这么多
点赞 回复 分享
发布于 2022-03-20 16:26
第三题应该是bfs+最优匹配
点赞 回复 分享
发布于 2022-03-17 22:35
看这第三题代码量,幸亏我果断放弃去调前面的题去了
点赞 回复 分享
发布于 2022-03-17 22:23
第二题题目意思有中间必须连续吗??? 我以为八个方向所有可以达到的棋子。。。
点赞 回复 分享
发布于 2022-03-17 22:22
我看第一题太麻烦了,就去做第二第三题了,第二题搞完,去第三题也是用暴搜做,结果TLE了😅,心态崩了,最后第一题的时间也没了
点赞 回复 分享
发布于 2022-03-17 22:18
第一题每行要输出string?这么操蛋的吗
点赞 回复 分享
发布于 2022-03-17 22:17

相关推荐

快点约我面试吧
投递百度等公司10个岗位
点赞 评论 收藏
分享
06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
在等offer的火锅...:我去履历这么好,都找不到工作吗?
点赞 评论 收藏
分享
评论
6
39
分享

创作者周榜

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