暴力搜索

暴力搜索

一、板子

搜索分为两种,深度优先搜索和广度优先搜索。概念这里不多阐述,现在给出板子。

DFS

void DFS(int x,int depth){//x是目前正在搜索的量,depth是搜索深度
    if(边界条件){
        执行终止语句;
        return;
    }
    if(没访问过){
        DFS(下一步要搜索的量,depth+1);
        标记已访问;
    }
}

BFS

void BFS(){
    queue<int>q;
    q.push(起始元素);
    标记起始元素已访问;
    while(!q.empty()){
        int temp=q.front();//取出队首元素
        q.pop();
        if(边界条件)return;
        if(没访问过){
            q.push(下一步要搜索的量);
            标记已访问;
        }
    }
}

二、例题

  • P1706 全排列问题

    对于这种暴力搜索出答案的问题,一般都要使用 DFS。

    我们在 DFS 中传入在全排列序列中当前搜到了第几位

    对于每个数字,用一个数组 vis 记录某一种数字是否被用过,如果被用过,那么不搜索这个数字,否则将目前数位上的数字赋值为这个数字,标记 vis 数组,然后继续搜索。

    如果位数恰好等于 n,那么证明搜到边界,输出数组中存入的结果即可。

    我们在 DFS 后还需要进行回溯,即标记这个数字没有被访问过,产生新一轮的可能性。

  • P1219 [USACO1.5] 八皇后 Checker Challenge

    记录每一行放置的皇后的位置,然后记录这个皇后所影响的列和斜线,以此为 vis 数组进行搜索。

    记得回溯,即在 DFS 之后对标记数组置 0。

    如果搜索的深度(即皇后个数)大于行数,那么直接打印方案,并终止搜索。

  • P1443 马的遍历

    广搜板子,注意板子咋写。

  • P1135 奇怪的电梯

    把每个合法操作视为两层之间的连边,那么本题就是求无权图的最短路径。开一个数组 dis[i],表示到第 i 层的最短路径。

    当一个节点 i 将要扩展时,需要扩展到 i+a[i]i-a[i],注意判断合法性。

    当第一次扩展到节点 b 时,当前的 dis[b] 就是答案。

  • P1019 [NOIP 2000 提高组] 单词接龙

    首先我们用模拟法预处理出某两个字符串如果能被连接,那么它们互相重合的部分的长度是多少。用一个二维数组记录。

    然后开始搜索。对于每一个被搜索的单词,将其 vis 数组自增,表示多访问了一次;如果访问次数超过两次则代表不合法。这一点和普通板子题不太一样。

    如果对于这个被搜索的单词和某个正在枚举的单词能够互相匹配,那么进行进一步的扩展搜索。

    注意,可以在 DFS 函数里把目前接龙出来的字符串传进去,便于统计答案。每次搜索时,都更新答案为接龙字符串的最大值。

  • P1032 [NOIP 2002 提高组] 字串变换

    首先用一个 vector<pair<string,string>> 存储所有字串变换的规则。

    然后从原始字符串开始 BFS,用 find 方法寻找当前字符串里有没有当前规则能变换的子串,如果有,则变换,然后入队。

    对于每个队中元素,记录变换次数,如果次数大于 10,则说明无解;否则输出第一个等于目标字符串的变换次数。

posted @ 2025-11-01 08:34  L-Coding  阅读(7)  评论(0)    收藏  举报