一、简单搜索
FallenGemini

AcWing 1114 棋盘问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
搜索、状压、记忆化
*/
int solve() {
int n,k;
std::cin >> n >> k;
if(n == -1 && k == -1) {
return 0;
}
std::vector<std::string> map(n);
for(int i = 0; i < n; i++) {
std::cin >> map[i];
}

std::vector f(n, std::vector<int> (1 << n, -1));

auto dfs = [&](auto dfs, int step, int status, int num) {
if(step == n) {
return num == k ? 1 : 0;
}
if(num == k) {
return f[step][status] = 1;
}
if(f[step][status] != -1) {
return f[step][status];
}
int res = 0;
res += dfs(dfs, step + 1, status, num);
for(int i = 0; i < n; i++) {
if(map[step][i] != '#') continue;
if((status >> i) & 1) continue;
res += dfs(dfs, step + 1, status | (1 << i), num + 1);
}
return f[step][status] = res;
};

std::cout << dfs(dfs,0,0,0) << '\n';
return 1;
}

AcWing 1096 地牢大师

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
bfs
*/
int solve() {
int L,R,C;
std::cin >> L >> R >> C;
if(L == 0 && R == 0 && C == 0) {
return 0;
}
std::vector map(L,std::vector<std::string> (R));
std::vector f(L, std::vector (R, std::vector<int> (C, 1e9)));
int sx,sy,sz,ex,ey,ez;
for(int i = 0; i < L; i++) {
for(int j = 0; j < R; j++) {
std::cin >> map[i][j];
for(int k = 0; k < C; k++) {
if(map[i][j][k] == 'S') {
sx = i; sy = j; sz = k;
}
if(map[i][j][k] == 'E') {
ex = i; ey = j; ez = k;
}
}
}
}

auto bfs = [&]() -> void {
f[sx][sy][sz] = 0;
std::array<std::array<int,3>,6> next =
{{{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}}};
std::queue<int> X,Y,Z;
X.push(sx);Y.push(sy);Z.push(sz);

while(!X.empty()) {
int x = X.front(), y = Y.front(), z = Z.front();
X.pop();Y.pop();Z.pop();
for(int i = 0; i < 6; i++) {
int tx = x + next[i][0], ty = y + next[i][1], tz = z + next[i][2];
if(tx < 0 || tx >= L || ty < 0 || ty >= R || tz < 0 || tz >= C) continue;
if(map[tx][ty][tz] == '#') continue;
if(f[tx][ty][tz] != 1e9) continue;
f[tx][ty][tz] = f[x][y][z] + 1;
X.push(tx);Y.push(ty);Z.push(tz);
}
}
};

bfs();
if(f[ex][ey][ez] == 1e9) {
std::cout << "Trapped!\n";
}
else {
std::cout << "Escaped in " << f[ex][ey][ez] << " minute(s).\n";
}

return 1;
}

AcWing 1100 抓住那头牛

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
bfs
*/
void solve() {
int n,k;
std::cin >> n >> k;
std::vector<int> f(2e5,1e9);
std::queue<int> q;

f[n] = 0;
q.push(n);
while(f[k] == 1e9) {
int x = q.front();
q.pop();
if(x && f[x - 1] == 1e9) {
f[x - 1] = f[x] + 1;
q.push(x - 1);
}
if(f[x + 1] == 1e9) {
f[x + 1] = f[x] + 1;
q.push(x + 1);
}
if(x < k && f[2 * x] == 1e9) {
f[2 * x] = f[x] + 1;
q.push(2 * x);
}
}

std::cout << f[k] << '\n';
}

AcWing 4218 翻转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
枚举
*/
void solve() {
int M,N;
std::cin >> M >> N;

std::vector<int> map(M);
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
int x;
std::cin >> x;
map[i] = (map[i] << 1) + x;
}
}

// 当前行的状态 status,当前行改变的位置 change
// 返回之后当前行的状态,即下一行需要改变的位置
auto check = [&](int status, int change) {
for(int i = 0; i < N; i++) {
if((change >> i) & 1) {
if(i) status ^= (1 << (i - 1));
status ^= (1 << i);
if(i + 1 < N) status ^= (1 << (i + 1));
}
}
return status;
};

std::vector<int> res(M);
int Num = 1e9;
for(int i = 0; i < (1 << N); i++) {
std::vector<int> temp(M);
int status = map[0], change = i;
for(int j = 0; j < M; j++) {
temp[j] = change;
change = check(status, change);
if(j + 1 < M) status = map[j + 1] ^ temp[j];
}

if(change != 0) continue;
int num = 0;
for(int val : temp) {
while(val) {
if(val & 1) num++;
val >>= 1;
}
}
if(num < Num) {
Num = num;
res = temp;
}
}

if(Num == 1e9) {
std::cout << "IMPOSSIBLE\n";
}
else {
for(int i = 0; i < M; i++) {
for(int j = N - 1; j >= 0; j--) {
std::cout << ((res[i] >> j) & 1) << " \n"[j == 0];
}
}
}
}

AcWing 4219 找倍数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int solve() {
int n;
std::cin >> n;

if(!n) return 0;

auto bfs = [&]() -> std::string {
std::queue<std::pair<std::string,int>> q;
q.push(std::make_pair("1",1));
while(true) {
std::string s = q.front().first;
int val = q.front().second;
if(!val) break;
q.pop();

q.push(std::make_pair(s + "0", (val * 10) % n));
q.push(std::make_pair(s + "1", (val * 10 + 1) % n));
}
return q.front().first;
};

std::cout << bfs() << '\n';
return 1;
}

AcWing 4220 质数路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
std::vector<bool> book(10000);
void init() {
for(int i = 1000; i <= 9999; i++) {
book[i] = true;
for(int j = 2; j * j <= i; j++) {
if(i % j == 0) book[i] = false;
}
}
}
void solve() {
int A,B;
std::cin >> A >> B;

std::vector<int> f(10000,1e9);
f[A] = 0;

std::queue<int> q;
q.push(A);
while(!q.empty()) {
int val = q.front();
q.pop();

int temp;
for(int i = 1; i <= 9; i++) {
temp = val % 1000 + i * 1000;
if(book[temp] && f[temp] == 1e9) {
f[temp] = f[val] + 1;
q.push(temp);
}
}
for(int i = 0; i <= 9; i++) {
temp = (val / 1000) * 1000 + val % 100 + i * 100;
if(book[temp] && f[temp] == 1e9) {
f[temp] = f[val] + 1;
q.push(temp);
}

temp = (val / 100) * 100 + val % 10 + i * 10;
if(book[temp] && f[temp] == 1e9) {
f[temp] = f[val] + 1;
q.push(temp);
}

temp = (val / 10) * 10 + i;
if(book[temp] && f[temp] == 1e9) {
f[temp] = f[val] + 1;
q.push(temp);
}
}
}

if(f[B] == 1e9) std::cout << "Impossible\n";
else std::cout << f[B] << '\n';
}

AcWing 4221 洗牌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int solve() {
int C;
std::cin >> C;
std::string A,B,S,temp;
std::cin >> A >> B >> S;

std::map<std::string,bool> map;
int res = 0;
while(true) {
res++;
temp = "";
for(int i = 0; i < C; i++) {
temp = temp + B[i] + A[i];
}

if(temp == S) return res;
if(map[temp]) return -1;
map[temp] = true;
A = temp.substr(0,C);
B = temp.substr(C,C);
}

}

AcWing 4222 罐子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
void solve() {
int A,B,C;
std::cin >> A >> B >> C;

std::vector f(A + 1,std::vector<int> (B + 1,1e9));
std::vector op(A + 1,std::vector<std::string> (B + 1));
f[0][0] = 0;

std::queue<std::pair<int,int>> q;
q.push(std::make_pair(0,0));

while(!q.empty()) {
int x = q.front().first;
int y = q.front().second;
if(x == C || y == C) break;
q.pop();

if(f[0][y] == 1e9) {
f[0][y] = f[x][y] + 1;
op[0][y] = op[x][y] + "1";
q.push(std::make_pair(0,y));
}
if(f[x][0] == 1e9) {
f[x][0] = f[x][y] + 1;
op[x][0] = op[x][y] + "2";
q.push(std::make_pair(x,0));
}
if(f[A][y] == 1e9) {
f[A][y] = f[x][y] + 1;
op[A][y] = op[x][y] + "3";
q.push(std::make_pair(A,y));
}
if(f[x][B] == 1e9) {
f[x][B] = f[x][y] + 1;
op[x][B] = op[x][y] + "4";
q.push(std::make_pair(x,B));
}

int tempA = std::min(A,x + y), tempB = std::max(0, x + y - A);
if(f[tempA][tempB] == 1e9) {
f[tempA][tempB] = f[x][y] + 1;
op[tempA][tempB] = op[x][y] + "5";
q.push(std::make_pair(tempA,tempB));
}

tempA = std::max(0, x + y - B), tempB = std::min(B, x + y);
if(f[tempA][tempB] == 1e9) {
f[tempA][tempB] = f[x][y] + 1;
op[tempA][tempB] = op[x][y] + "6";
q.push(std::make_pair(tempA,tempB));
}
}

int resA = q.front().first,resB = q.front().second;
if(resA != C && resB != C) {
std::cout << "impossible\n";
return;
}

std::cout << f[resA][resB] << '\n';
for(int i = 0; i < f[resA][resB]; i++) {
int val = op[resA][resB][i] - '0';
switch(val) {
case 1: std::cout << "DROP(1)" << '\n';break;
case 2: std::cout << "DROP(2)" << '\n';break;
case 3: std::cout << "FILL(1)" << '\n';break;
case 4: std::cout << "FILL(2)" << '\n';break;
case 5: std::cout << "POUR(2,1)" << '\n';break;
case 6: std::cout << "POUR(1,2)" << '\n';break;
}
}
}

AcWing 4223 点火游戏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
int solve() {
int N,M;
std::cin >> N >> M;

std::vector<std::string> map(N);
for(int i = 0; i < N; i++) {
std::cin >> map[i];
}

std::vector<std::pair<int,int>> grass;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(map[i][j] == '#') {
grass.push_back(std::make_pair(i,j));
}
}
}

auto bfs = [&](std::pair<int,int> a){
std::array<std::array<int,2>,4> nxt = {{{0,1},{0,-1},{1,0},{-1,0}}};
std::vector f(N,std::vector<int> (M,1e9));
f[a.first][a.second] = 0;

std::queue<std::pair<int,int>> q;
q.push(a);
while(!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= N || ty < 0 || ty >= M) continue;
if(map[tx][ty] == '.') continue;
if(f[tx][ty] != 1e9) continue;
f[tx][ty] = f[x][y] + 1;
q.push(std::make_pair(tx,ty));
}
}

return f;
};

std::vector dis(grass.size(),std::vector (N,std::vector<int> (M)));
for(int i = 0; i < grass.size(); i++) {
dis[i] = bfs(grass[i]);
}

int ans = 1e9;
for(int i = 0; i < grass.size(); i++) {
for(int j = i; j < grass.size(); j++) {
int val = 0;
for(int k = 0; k < grass.size(); k++) {
int x = grass[k].first,y = grass[k].second;
val = std::max(val,
std::min(dis[i][x][y],dis[j][x][y]));
}
ans = std::min(ans, val);
}
}
return ans == 1e9 ? -1 : ans;
}

AcWing 4224 起火迷宫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void solve() {
int R,C;
std::cin >> R >> C;

std::vector<std::string> map(R);
for(int i = 0; i < R; i++) {
std::cin >> map[i];
}

std::queue<std::pair<int,int>> J,F;
for(int i = 0; i < R; i++) {
for(int j = 0; j < C; j++) {
if(map[i][j] == 'J') J.push(std::make_pair(i,j));
if(map[i][j] == 'F') F.push(std::make_pair(i,j));
}
}

int time = 0;
bool flag = false;
std::array<std::array<int,2>,4> nxt = {{{1,0},{-1,0},{0,1},{0,-1}}};
while(!J.empty()) {
time++;
std::queue<std::pair<int,int>> temp;
while(!F.empty()) {
int x = F.front().first, y = F.front().second;
F.pop();
for(int i = 0; i < 4; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= R || ty < 0 || ty >= C) continue;
if(map[tx][ty] == '#' || map[tx][ty] == 'F') continue;
map[tx][ty] = 'F';
temp.push(std::make_pair(tx,ty));
}
}
std::swap(temp,F);
while(!J.empty()) {
int x = J.front().first, y = J.front().second;
J.pop();
for(int i = 0; i < 4; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= R || ty < 0 || ty >= C) {
flag = true;
break;
}
if(map[tx][ty] != '.') continue;
map[tx][ty] = 'J';
temp.push(std::make_pair(tx,ty));
}
}
std::swap(temp,J);
if(flag) break;
}

if(flag) std::cout << time << '\n';
else std::cout << "IMPOSSIBLE\n";
}

AcWing 1076 迷宫问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void solve() {
int n;
std::cin >> n;

std::vector map(n,std::vector<int> (n));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
std::cin >> map[i][j];
}
}

std::vector pre(n,std::vector<std::pair<int,int>> (n,std::pair(-1,-1)));
std::queue<std::pair<int,int>> q;
std::array<std::array<int,2>,4> nxt = {{{1,0},{-1,0},{0,1},{0,-1}}};
q.push(std::pair(0,0));
pre[0][0] = std::pair(-2,-2);
while(pre[n - 1][n - 1] == std::pair(-1,-1)) {
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= n) continue;
if(map[tx][ty] == 1) continue;
if(pre[tx][ty] == std::pair(-1,-1)) {
pre[tx][ty] = std::pair(x,y);
q.push(std::pair(tx,ty));
}
}
}

std::stack<std::pair<int,int>> stack;
std::pair<int,int> res = std::pair(n - 1, n - 1);
while(res != std::pair(-2,-2)) {
stack.push(res);
res = pre[res.first][res.second];
}

while(!stack.empty()) {
std::cout << stack.top().first << ' ' << stack.top().second << '\n';
stack.pop();
}
}

AcWing 4225 石油储备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
int solve() {
int n,m;
std::cin >> n >> m;
if(n == 0 && m == 0)
return 0;

std::vector<std::string> map(n);
for(int i = 0;i < n; i++) {
std::cin >> map[i];
}

auto bfs = [&](int sx,int sy) -> void {
std::queue<std::pair<int,int>> q;
std::array<std::array<int,2>,8> nxt = {{{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}};

q.push(std::pair<int,int> (sx,sy));
map[sx][sy] = '*';

while(!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 8; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(map[tx][ty] == '*') continue;
map[tx][ty] = '*';
q.push(std::pair<int,int> (tx,ty));
}
}
};

int res = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(map[i][j] == '@') {
bfs(i,j);
res++;
}
}
}

std::cout << res << '\n';
return 1;
}

AcWing 4226 非常可乐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
int solve() {
int S,N,M;
std::cin >> S >> N >> M;
if(S == 0 && N == 0 && M == 0)
return 0;

std::array<int,3> begin = {S,0,0};
std::map<std::array<int,3>,int> map;
std::queue<std::array<int,3>> q;
map[begin] = 1;
q.push(begin);

auto check = [&](std::array<int,3> x) -> bool {
std::sort(x.begin(),x.end());
if(x[0] == 0 && x[1] == S / 2 && x[2] == S / 2) return true;
return false;
};

while(!q.empty()) {
std::array<int,3> A = q.front(),temp;
q.pop();
temp = A;
temp[1] = std::min(N,A[0] + A[1]);
temp[0] = std::max(0,A[0] + A[1] - N);
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}

temp = A;
temp[0] = A[0] + A[1];
temp[1] = 0;
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}

temp = A;
temp[2] = std::min(M,A[0] + A[2]);
temp[0] = std::max(0,A[0] + A[2] - M);
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}

temp = A;
temp[0] = A[0] + A[2];
temp[2] = 0;
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}

temp = A;
temp[2] = std::min(M,A[1] + A[2]);
temp[1] = std::max(0,A[1] + A[2] - M);
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}

temp = A;
temp[1] = std::min(N,A[1] + A[2]);
temp[2] = std::max(0,A[1] + A[2] - N);
if(map[temp] == 0) {
map[temp] = map[A] + 1;
if(check(temp)) {
std::cout << map[temp] - 1 << '\n';
return 1;
}
q.push(temp);
}
}
std::cout << "NO\n";
return 1;
}

AcWing 4227 找路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void solve(int n,int m) {
std::vector<std::string> map(n);
for(int i = 0; i < n; i++) {
std::cin >> map[i];
}

auto bfs = [&](int sx,int sy) {
std::vector f(n,std::vector<int> (m,1e9));
std::array<std::array<int,2>,4> nxt = {{{1,0},{-1,0},{0,1},{0,-1}}};
std::queue<std::pair<int,int>> q;

f[sx][sy] = 0;
q.push(std::pair<int,int> (sx,sy));

while(!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++) {
int tx = x + nxt[i][0], ty = y + nxt[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(map[tx][ty] == '#') continue;
if(f[tx][ty] != 1e9) continue;
f[tx][ty] = f[x][y] + 11;
q.push(std::pair<int,int> (tx,ty));
}
}

return f;
};

std::vector Y(n,std::vector<int> (m)),M(n,std::vector<int> (m));
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(map[i][j] == 'Y') Y = bfs(i,j);
if(map[i][j] == 'M') M = bfs(i,j);
}
}

int res = 1e9;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(map[i][j] == '@') {
res = std::min(res, Y[i][j] + M[i][j]);
}
}
}
std::cout << res << '\n';
}