Table of contents
AcWing 93. Recursive implementation of combined enumeration
AcWing95. Puzzling switch
Description
Have you ever played the "pull the lights" game?
2525 lights are arranged in a 5×55×5 square.
Each light has a switch that the player can change its state.
At each step, the player can change the state of a certain light.
When the player changes the state of a light, a chain reaction will occur: the lights adjacent to the light, up, down, left, and right will also change their states accordingly.
We use the number 11 for an on light and the number 00 for an off light.
The following state
10111
01101
10111
10000
11011
After changing the state of the top left light it will become:
01111
11101
10111
10000
11011
After changing the light in the middle of it, the state will become:
01111
11001
11001
10100
11011
Given some initial state of the game, write a program to determine whether it is possible for a player to turn on all the lights within 66 moves.
input format
The first line inputs a positive integer n, representing a total of n initial states of the game to be solved in the data.
The following lines of data are divided into n groups, each group of data has 5 lines, and each line has 5 characters.
Each set of data describes the initial state of a game.
Each set of data is separated by a blank line.
output format
A total of n lines of data are output, and each line has an integer less than or equal to 6, which indicates the minimum number of steps required to make all the lights brighten for the corresponding game state in the input data.
For a certain initial state of the game, if all the lights cannot be turned on within 6 steps, output −1.
data range
0 < n ≤ 500
Input sample:
3
00111
01011
10001
11010
11100
11101
11101
11110
11111
11111
01111
11111
11111
11111
11111
Sample output:
3
2
-1
Difficulty: Moderate |
Time/space limit: 1s / 256MB |
Total Passes: 24338 |
Total attempts: 39223 |
Source: "Advanced Guide to Algorithm Competitions" |
Algorithm label |
AcCode
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 6;
char g[N][N], backup[N][N];
int dx[5] = {-1, 0, 1, 0, 0}, dy[5] = {0, 1, 0, -1, 0};
void turn(int x, int y)
{
for (int i = 0; i < 5; i ++ )
{
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a >= 5 || b < 0 || b >= 5) continue; // 在边界外,直接忽略即可
g[a][b] ^= 1;
}
}
int main()
{
int n;
cin >> n;
while (n -- )
{
for (int i = 0; i < 5; i ++ ) cin >> g[i];
int res = 10;
//二进制数中1表示要按,0表示不按
for (int op = 0; op < 1 << 5; op ++ ) //32中方案(op代表的不是灯状态,而是按或者不按)
{
memcpy(backup, g, sizeof g);
int step = 0;
for (int i = 0; i < 5; i ++ )
if (op >> i & 1)
{
step ++ ;
turn(0, i);
}
for (int i = 0; i < 4; i ++ )
for (int j = 0; j < 5; j ++ )
if (g[i][j] == '0')
{
step ++ ;
turn(i + 1, j);
}
bool dark = false;
for (int i = 0; i < 5; i ++ )
if (g[4][i] == '0')
{
dark = true;
break;
}
if (!dark) res = min(res, step);
memcpy(g, backup, sizeof g);
}
if (res > 6) res = -1;
cout << res << endl;
}
return 0;
}
AcWing 93. Recursive implementation of combined enumeration
Randomly select m from the n integers 1∼n, and output all possible options.
input format
Two integers n, m separated by spaces on the same line.
output format
Output all solutions in ascending order, 1 per line.
First, the numbers in the same line are arranged in ascending order, and two adjacent numbers are separated by a space.
Secondly, for two different rows, compare the numbers corresponding to the subscripts one by one, and the one with the smaller lexicographical order is ranked first (for example, the 1 3 5 7
first 1 3 6 8
row).
data range
n > 0
0 ≤ m ≤ n
n + (n−m) ≤ 25
Input sample:
5 3
Sample output:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 30;
int n, m;
int way[N];
void dfs(int u, int start)
{
if (u + n - start < m) return; // 剪枝
if (u == m + 1) //边界
{
for (int i = 1; i <= m; i ++ ) printf("%d ", way[i]);
puts("");
return;
}
for (int i = start; i <= n; i ++ )
{
way[u] = i;
dfs(u + 1, i + 1);
way[u] = 0; // 恢复现场
}
}
int main()
{
scanf("%d%d", &n, &m);
//第一个i表示当前从第一位开始枚举,第二个1表示可以从1枚举
dfs(1, 1);
return 0;
}
AcWing 1209. with fractions
100 can be expressed as a fraction: 100=3+69258/714
It can also be expressed as: 100=82+3546/197
Pay attention to the characteristics: in the band fraction, the numbers 1∼9 appear and only appear once (excluding 0).
With fractions like this, 100 has 11 representations.
input format
a positive integer.
output format
The output and input numbers use the digits 1∼91∼9 to form all kinds of numbers represented by fractions without repetition or omission.
data range
Input sample 1:
100
Output sample 1:
11
Input sample 2:
105
Output sample 2:
6
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10;
int n;
bool st[N], backup[N];
int ans;
bool check(int a, int c)
{
long long b = n * (long long)c - a * c;
if (!a || !b || !c) return false;
memcpy(backup, st, sizeof st);
while (b)
{
int x = b % 10; // 取个位
b /= 10; // 个位删掉
if (!x || backup[x]) return false;
backup[x] = true;
}
for (int i = 1; i <= 9; i ++ )
if (!backup[i])
return false;
return true;
}
void dfs_c(int u, int a, int c)
{
if (u > 9) return;
if (check(a, c)) ans ++ ;
for (int i = 1; i <= 9; i ++ )
if (!st[i])
{
st[i] = true;
dfs_c(u + 1, a, c * 10 + i);
st[i] = false;
}
}
void dfs_a(int u, int a)
{
if (a >= n) return;
if (a) dfs_c(u, a, 0);
for (int i = 1; i <= 9; i ++ )
if (!st[i])
{
st[i] = true;
dfs_a(u + 1, a * 10 + i);
st[i] = false;
}
}
int main()
{
cin >> n;
dfs_a(0, 0);
cout << ans << endl;
return 0;
}
AcWing 1208. Coin Flip
Xiao Ming is playing a "coin flip" game.
There are several coins in a row on the table. We use * for heads and o for tails (which is a lowercase letter, not zero).
For example, it might be the case that:**oo***oooo
If the two coins on the left are flipped simultaneously, this becomes:oooo***oooo
Now Xiaoming's question is: If the initial state and the target state to be achieved are known, and only two adjacent coins can be flipped at the same time, how many times should the flip be at least for a specific situation?
We agree: flipping two adjacent coins is called a one-step operation.
input format
Two strings of equal length represent the initial state and the target state to be achieved respectively.
output format
An integer representing the minimum number of steps
data range
None of the input strings are longer than 100.
The data guarantees that the answer must have a solution.
Input sample 1:
**********
o****o****
Output sample 1:
5
Input sample 2:
*o**o***o***
*o***o**o***
Output sample 2:
1
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100;
int n;
char start[N],aim[N];
void turn(int i)
{
if(start[i] == '*') start[i] = 'o';
else start[i] = '*';
}
int main()
{
cin >> start >> aim;
n = strlen(start);
int res = 0;
for(int i = 0; i <= n ;i ++)
if(start[i] != aim[i] )
{
turn(i),turn(i + 1);
res ++ ;
}
cout << res << endl;
return 0;
}