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

相关推荐
南东山人1 分钟前
一文说清:C和C++混合编程
c语言·c++
LNTON羚通1 小时前
摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现
算法·目标检测·音视频·监控·视频监控
哭泣的眼泪4082 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
Ysjt | 深3 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
ephemerals__3 小时前
【c++丨STL】list模拟实现(附源码)
开发语言·c++·list
Microsoft Word3 小时前
c++基础语法
开发语言·c++·算法
天才在此3 小时前
汽车加油行驶问题-动态规划算法(已在洛谷AC)
算法·动态规划
一只小小汤圆3 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade
legend_jz4 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法