蓝桥杯-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

相关推荐
haaaaaaarry5 分钟前
【分治法】线性时间选择问题
数据结构·算法
CS创新实验室14 分钟前
计算机考研之数据结构:P 问题和 NP 问题
数据结构·考研·算法
OTWOL44 分钟前
【C++编程入门基础(一)】
c++·算法
谏君之1 小时前
C语言实现的常见算法示例
c语言·算法·排序算法
宇寒风暖1 小时前
侯捷 C++ 课程学习笔记:内存管理与工具应用
c++·笔记·学习
机器视觉知识推荐、就业指导1 小时前
【数字图像处理二】图像增强与空域处理
图像处理·人工智能·经验分享·算法·计算机视觉
Smile丶凉轩2 小时前
数据库面试知识点总结
数据库·c++·mysql
Want5952 小时前
C/C++跳动的爱心
c语言·开发语言·c++
laimaxgg2 小时前
Qt常用控件之数字显示控件QLCDNumber
开发语言·c++·qt·qt5·qt6.3
蓝天扶光2 小时前
c++贪心系列
开发语言·c++