网易笔试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++
*/ 

