蓝桥杯-dfs搜索模板题(二)

蓝桥杯-dfs搜索模板题(二)

  • [P1683 入门](#P1683 入门)
  • [P1596[USACO10OCT] Lake Counting S](#P1596[USACO10OCT] Lake Counting S)
  • [1114 棋盘 acwing](#1114 棋盘 acwing)
  • [P1025 [NOIP2001 提高组] 数的划分](#P1025 [NOIP2001 提高组] 数的划分)
  • [P1019 [NOIP2000 提高组] 单词接龙](#P1019 [NOIP2000 提高组] 单词接龙)
  • 结语

P1683 入门

这道题没有回溯的必要,重复走也不计数。最开始的部分++要补上。

c 复制代码
#include<bits/stdc++.h>

using namespace std;

const int N = 30;
int n, m;
char g[N][N];
bool st[N][N];
int res = 0;//走过的瓷砖数 

int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };

void dfs(int x, int y)
{
	//	dfs(x+1,y);
	//	dfs(x,y+1);
	//	dfs(x-1;y);
	//	dfs(x,y-1);
	for (int i = 0; i < 4; i++)
	{
		int a = x + dx[i];
		int b = y + dy[i];
		if (a < 0 || a >= n || b < 0 || b >= m)continue;
		if (g[a][b] != '.')continue;
		if (st[a][b])continue;

		st[a][b] = true;
		res++;

		dfs(a, b);
	}

}


int main()
{
	cin >> m >> n;
	for (int i = 0; i < n; i++)
	{
		scanf("%s", &g[i]);
		//		for(int j=0;j<m;j++)
		//			scanf("%c",&g[i][j]); 

	}
	for (int i = 0; i < n; i++)
	{

		for (int j = 0; j < m; j++)
		{
			if (g[i][j] == '@')
			{
				st[i][j] = true;
				dfs(i, j);
			}

		}

	}
	res++;
	cout << res;

	return 0;
}

P1596[USACO10OCT] Lake Counting S

连起来的水坑只算一次

c 复制代码
#include<bits/stdc++.h>
using namespace std;

const int N = 110;


int n, m;
char g[N][N];
bool st[N][N];
int res;

int dx[] = { 1,1,1,0,0,-1,-1,-1 };
int dy[] = { -1,0,1,-1,1,-1,0,1 };

void dfs(int x, int y)
{
    for (int i = 0; i < 8; i++)
    {
        int a = x + dx[i];
        int b = y + dy[i];

        if (a < 0 || a >= n || b < 0 || b >= m)continue;
        if (g[a][b] != 'W')continue;
        if (st[a][b])continue;

        st[a][b] = true;
        dfs(a, b);
    }
}




int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        scanf("%s", g[i]);

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (g[i][j] == 'W' && !st[i][j])
            {
                st[i][j] = true;
                dfs(i, j);
                res++;
            }


    cout << res;

    return 0;
}

1114 棋盘 acwing

注意搜索要逐层递推下去,这也是dfs(x + 1, cnt);的作用。

这种情况比如棋子比行数少,前面放完有可能后面就不放了

c 复制代码
#include<bits/stdc++.h>
using namespace std;

const int N = 110;

int n, k;
char g[N][N];
bool st[N];
int res = 0;

void dfs(int x, int cnt)
{
	if (cnt == k)
	{
		
		res++;
		return;
	}

	if (x >= n)return;

	for (int i = 0; i < n; i++)
	{
		if (!st[i] && g[x][i] == '#')
		{
			st[i] = true;
			dfs(x + 1, cnt + 1);
			st[i] = false;
		}
	}
	dfs(x + 1, cnt);
}


int main()
{

	while (cin >> n >> k, n > 0 && k > 0)
	{

		for (int i = 0; i < n; i++)  scanf("%s", g[i]);
		
		res = 0;
		dfs(0, 0);

		printf("%d\n", res);
		

	}
	
	return 0;

}

P1025 [NOIP2001 提高组] 数的划分

c 复制代码
#include<bits/stdc++.h>

using namespace std;

const int N = 10;

int n, k;
int arr[N];
int res = 0;

void dfs(int x, int start, int sum)
{


    if (x > k)
    {
        if (sum == n)
        {
            res++;

        }
        return;
    }


    for (int i = start; sum + i * (k - x + 1) <= n; i++)
    {
        arr[x] = i;
        dfs(x + 1, i, sum + i);
        arr[x] = 0;
    }
}


int main()
{
    cin >> n >> k;
    dfs(1, 1, 0);
    cout << res;
}

P1019 [NOIP2000 提高组] 单词接龙

细节较多。判断两个字符串是否能接龙,能接龙多少通过k的枚举实现。

并且重叠的部分越短越好,因为整体长度要尽可能长。

c 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 30;

int n;
string words[N];//存单词 
int used[N];//记录每个单词的使用次数 
int g[N][N];//g[i][j]存第i个单词能否接到第j个单词后面,重合的长度 
int res;

void dfs(string dragon, int x)
{
	res = max(res, (int)dragon.size());
	used[x]++;
	for (int i = 0; i < n; i++)
	{
		if (g[x][i] && used[i] < 2)
		{
			dfs(dragon + words[i].substr(g[x][i]), i);
		}
	}
	used[x]--;
}



int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)cin >> words[i];

	char start;
	cin >> start;

	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			string a = words[i], b = words[j];
			for (int k = 1; k < min(a.size(), b.size()); k++)
			{
				if (a.substr(a.size() - k, k) == b.substr(0, k))
				{
					g[i][j] = k;
					break;//尽可能短才可以 
				}
			}
		}
	for (int i = 0; i < n; i++)
	{
		if (words[i][0] == start)
		{
			dfs(words[i], i);//
		}
	}
	cout << res;
}

结语

整理自链接: link

相关推荐
saltymilk15 小时前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程
感哥16 小时前
C++ lambda 匿名函数
c++
沐怡旸1 天前
【底层机制】std::unique_ptr 解决的痛点?是什么?如何实现?怎么正确使用?
c++·面试
感哥1 天前
C++ 内存管理
c++
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了1 天前
AcWing学习——双指针算法
c++·算法
感哥1 天前
C++ 指针和引用
c++