竞赛班搜索专题(不是我写的)
发的md 传博客好看点(
二编:F题if(y+n-x+1<ans) return; 冗余
五、搜索专题题解
A.
//硬币翻转,判断相邻不同个数即可,注意末尾的0、1判断
#include <bits/stdc++.h>
#define fer(i, m, n) for (int i = m; i < n;i++)
using namespace std;
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
// #define x first
// #define y second
void solve(){
#include <bits/stdc++.h>
#define fer(i, m, n) for (int i = m; i < n;i++)
using namespace std;
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
// #define x first
// #define y second
void solve(){
string s;
cin >> s;
int ans = 0;
for (int i = 0; i < s.length() - 1; i++)
{
if (s[i] != s[i + 1])
ans++;
}
if (s[s.length() - 1] == '0')
ans++;
cout << ans;
}
int main(){
// int t;
// cin >> t;
// while (t--){
// solve();
// }
// while(1){
solve();
// }
return 0;
// system("pause");
}
B.
//自然数的拆分,直接DFS
#include <bits/stdc++.h>
#define fer(i, m, n) for (int i = m; i < n;i++)
using namespace std;
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
int ans[1000], n;
void solve(int t,int sum){
if (sum == n){
// cout << n << '=';
fer(i,1,t){
cout << ans[i];
if(i != t-1)
cout << '+';
}
cout << endl;
}else{
fer(i,ans[t-1],n){
if(sum > n-i)
return;
ans[t] = i;
solve(t + 1, sum + i);
}
}
}
int main(){
cin >> n;
ans[0] = 1;
solve(1,0);
return 0;
}
C.
//同样,DFS
#include <bits/stdc++.h>
#define fer(i, m, n) for (int i = m; i < n;i++)
using namespace std;
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
int n,m,v[22],ans[22];
void solve(int t){
if(t==m){
fer(i,1,m+1){
printf("%3d", ans[i]);
}
printf("\n");
}else{
fer(i,ans[t]+1,n+1){
ans[t + 1] = i;
solve(t + 1);
}
}
}
int main(){
cin >> n >> m;
solve(0);
return 0;
}
D.
//跟C题差不多,DFS
#include <bits/stdc++.h>
#define fer(i, m, n) for (int i = m; i < n;i++)
using namespace std;
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
int n,m,v[22],ans[22];
void solve(int t){
if(t==n){
fer(i,1,n+1){
printf("%5d", ans[i]);
}
printf("\n");
}else{
fer(i,1,n+1){
if(!v[i]){
ans[t + 1] = i;
v[i] = 1;
solve(t + 1);
v[i] = 0;
}
}
}
}
int main(){
cin >> n;
solve(0);
return 0;
}
E.
//用DFS把所有情况罗列再比较一下即可
#include <bits/stdc++.h>
using namespace std;
int n;
int pay[21][21];
int Min = INT_MAX;
int sum = 0;
int book[21];
void dfs(int t)
{
if (t >= n)
{
if (Min > sum)
{
Min = sum;
return;
}
}
for (int i = 0; i < n; i++) {
if (!book[i])
{
book[i] = 1;
sum += pay[t][i];
if (sum < Min)
dfs(t + 1);
book[i] = 0;
sum -= pay[t][i];
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> pay[i][j];
}
book[i] = 0;
}
dfs(0);
cout << Min << endl;
return 0;
}
F.
//依旧是 DFS ,用一个二维数组记录两人的关系,然后根据判断在DFS内判断即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
int tu[105][105];
int n, m, ans = 0;
bool vis[110], rec[110];
void dfs(int x, int sum) {
if (x == n + 1) {
if (sum > ans) {
for (int i = 1; i <= n; i++) rec[i] = vis[i];
ans = sum;
}
return;
}
//if (sum + n - x + 1 < ans) return; //冗余了
int flag = 0;
for (int i = 1; i < x; i++) {
if (vis[i] && tu[i][x]) {
flag = 1;
break;
}
}
if (!flag) {
vis[x] = 1;
dfs(x + 1, sum + 1);
vis[x] = 0;
}
dfs(x + 1, sum);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, a, b; i <= m; i++) {
scanf("%d%d", &a, &b);
tu[a][b] = 1;
tu[b][a] = 1;
}
dfs(1, 0);
printf("%d\n", ans);
for (int i = 1; i <= n; i++)
printf("%d%c", rec[i], i == n ? '\n' : ' ');
return 0;
}
G.
// 利用 BFS 广搜,模拟乳草蔓延
#include <bits/stdc++.h>
#define fer(i, n) for (int i = 0; i < n; i++)
using namespace std;
int dx[8] = {1, 1, 1, 0, 0, -1, -1, -1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
int sx, sy, ex, ey, cx, cy, cstep, h, t, n, m, res;
struct State {
int x, y, step;
} q[10005];
int grid[105][105];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> ex >> ey;
swap(n, m);
swap(ex, ey);
fer(i, n) {
char s[105];
cin >> s;
fer(j, m) {
if (s[j] == '*') grid[i + 1][j + 1] = 1;
}
}
grid[ex][ey] = 1;
h = 0, t = 1, q[t].x = ex, q[t].y = ey;
while (h < t) {
h++;
cx = q[h].x, cy = q[h].y, cstep = q[h].step;
fer(i, 8) {
int nx = cx + dx[i], ny = cy + dy[i];
if (nx > 0 && nx <= n && ny > 0 && ny <= m && !grid[nx][ny]) {
grid[nx][ny] = 1;
t++;
q[t].x = nx, q[t].y = ny;
q[t].step = cstep + 1;
res = max(res, q[t].step);
}
}
}
cout << res << endl;
return 0;
}
H.
// 深度优先搜索 注意要先涂上面的色块
#include <bits/stdc++.h>
#define fer(i, n) for (int i = 0; i < n; i++)
//#include <bits/stdc++.h>
using namespace std;
struct str
{
int a1, a2, b1, b2, color;
} a[111000];
int b1[11000] = {0};
int b[110][110], n, m, ans = 999;
int b2[11000];
int cmp(str x, str y)
{
if (x.a1 != y.a1)
return x.a1 < y.a1;
return x.a2 < y.a2;
}
bool cha(int x)
{
for (int i = 0; i < n; i++)
{
if (b[x][i] && !b1[i])
return false;
}
return true;
}
void dfs(int x, int ji_lu, int sum)
{
if (x >= ans)
{
return;
}
if (sum == n)
{
ans = x;
return;
}
for (int i = 0; i < m; i++)
{
int h = 0;
if (b2[i] && i != ji_lu)
{
for (int j = 0; j < n; j++)
{
if (!b1[j] && a[j].color == i && cha(j))
{
b1[j] = 1;
h++;
}
else if (b1[j] && a[j].color == i)
b1[j]++;
}
if (h > 0)
{
dfs(x + 1, i, sum + h);
}
for (int j = n - 1; j >= 0; j--)
{
if (b1[j] == 1 && a[j].color == i && cha(j))
{
b1[j] = 0;
h--;
}
else if (b1[j] > 1 && a[j].color == i)
{
b1[j]--;
}
}
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i].a1 >> a[i].a2 >> a[i].b1 >> a[i].b2 >> a[i].color;
b2[a[i].color]++;
}
m = 19;
sort(a, a + n, cmp);
for (int i = 1; i < n; i++)
{
for (int j = i - 1; j >= 0; j--)
{
if (a[i].a1 == a[j].b1 && ((a[i].a2 >= a[j].a2 && a[i].a2 <= a[j].b2) || (a[i].b2 >= a[j].a2 && a[i].b2 <= a[j].b2)))
{
b[i][j] = 1;
}
}
}
dfs(0, 0, 0);
cout << ans;
}
I.
// 暴力搜索!
#include <bits/stdc++.h>
#define fer(i, n) for (int i = 0; i < n; i++)
using namespace std;
const int N = 9, M = 1 << N;
int grid[N][N];
int rows[N], cols[N], cells[3][3];
int setBits[M];
int bitLog[M];
int maxScore = -1;
void initialize(){
for (int i = 0; i < 9; i++)
rows[i] = cols[i] = (1 << 9) - 1;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
cells[i][j] = (1 << 9) - 1;
}
void update(int x, int y, int val, bool isSet){
int mask = 1 << (val - 1);
if (isSet){
grid[x][y] = val;
rows[x] -= mask, cols[y] -= mask, cells[x / 3][y / 3] -= mask;
}
else {
grid[x][y] = 0;
rows[x] += mask, cols[y] += mask, cells[x / 3][y / 3] += mask;
}
}
int getOptions(int x, int y){
return rows[x] & cols[y] & cells[x / 3][y / 3];
}
int calculateScore(int x, int y, int val){
return (min(min(x, 8 - x), min(y, 8 - y)) + 6) * val;
}
int getLowestBit(int x) {
return x & -x;
}
void dfs(int remain, int score){
if (remain == 0){
maxScore = max(maxScore, score);
return;
}
int minBits = 10, x, y;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
if (grid[i][j] == 0){
int options = getOptions(i, j);
if (setBits[options] < minBits){
minBits = setBits[options], x = i, y = j;
}
}
}
int options = getOptions(x, y);
for (int i = options; i != 0; i -= getLowestBit(i)){
int val = bitLog[getLowestBit(i)] + 1;
update(x, y, val, true);
dfs(remain - 1, score + calculateScore(x, y, val));
update(x, y, val, false);
}
}
int main(){
initialize();
for (int i = 0; i < 1 << 9; i++)
for (int j = 0; j < 9; j++)
setBits[i] += i >> j & 1;
for (int i = 0; i < 9; i++)
bitLog[1 << i] = i;
int remain = 0, score = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++){
cin >> grid[i][j];
if (grid[i][j] != 0) {
update(i, j, grid[i][j], true);
score += calculateScore(i, j, grid[i][j]);
}
else
remain++;
}
dfs(remain, score);
cout << maxScore << endl;
}
J.
// BFS + 模拟操作,注意可以把两行的化为一行处理
#include <bits/stdc++.h>
#define loop(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
string es, inp;
queue<pair<string, string>> q;
int dir[3][8] = {{7, 6, 5, 4, 3, 2, 1, 0}, {3, 0, 1, 2, 5, 6, 7, 4}, {0, 6, 1, 3, 4, 2, 5, 7}};
char mov[3] = {'A', 'B', 'C'};
map<string, int> vis;
string trans(string s, int id)
{
string res = s;
loop(i, 0, 7) res[i] = s[dir[id][i]];
return res;
}
void bfs()
{
q.push(make_pair("12345678", ""));
string cur, seq, nst, nseq;
while (!q.empty())
{
cur = q.front().first;
seq = q.front().second;
q.pop();
if (cur == es)
{
cout << seq.size() << endl << seq;
break;
}
loop(i, 0, 2)
{
nst = trans(cur, i);
if (vis.count(nst))
continue;
vis[nst] = 1;
nseq = seq + mov[i];
q.push(make_pair(nst, nseq));
}
}
}
int main()
{
loop(i, 1, 8)
{
cin >> inp;
es += inp;
}
bfs();
return 0;
}