竞赛班搜索专题(不是我写的)

发的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;
}

posted @ 2024-04-22 00:22  Z3phyπ  阅读(3)  评论(0编辑  收藏  举报