正经人不会想看的不用动脑子的内容之dfs与bfs的极限拉扯

dfs一般是一条路走到黑,解决多条路径;

/*
void dfs()
{
	for(拓展状态)
	{
		判断合法
		记录
		dfs(继续搜);
		回溯;
	}
}
*/

bfs一般为一层一层的扩展,解决最优解问题;

上题目吧!

题目描述

已知 nn 个整数 x_1,x_2,\cdots,x_nx1​,x2​,⋯,xn​,以及 11 个整数 kk(k

3+7+12=223+7+12=22

3+7+19=293+7+19=29

7+12+19=387+12+19=38

3+12+19=343+12+19=34

现在,要求你计算出和为素数共有多少种。

例如上例,只有一种的和为素数:3+7+19=293+7+19=29。

输入格式

第一行两个空格隔开的整数 n,kn,k(1 \le n \le 201≤n≤20,k

第二行 nn 个整数,分别为 x_1,x_2,\cdots,x_nx1​,x2​,⋯,xn​(1 \le x_i \le 5\times 10^61≤xi​≤5×106)。

输出格式

输出一个整数,表示种类数。

输入输出样例

输入 #1复制

4 3
3 7 12 19

输出 #1复制

1
#include 
using namespace std;
int n,k;
int ans=0;
int a[22];
bool shisushu(int x){
	for(int i=2;i*i<=x;i++){
		if(x%i==0) return false;//也可以用素数筛 
	}
	return true;
}
void dfs(int m,int sum,int start){
	if(m==k){
	    if(shisushu(sum)) ans++;
		return; 
	}
	for(int i=start;i>n>>k;
	for(int i=0;i>a[i];
	}
	dfs(0,0,0);
	cout<

标准写法

题目描述

Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John's field, determine how many ponds he has.

由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水('W') 或是旱地('.')。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。

输入格式

Line 1: Two space-separated integers: N and M * Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.

第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是'W'或'.',它们表示网格图中的一排。字符之间没有空格。

输出格式

Line 1: The number of ponds in Farmer John's field.

一行:水坑的数量

输入输出样例

输入 #1复制

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出 #1复制

3
#include 
using namespace std;
int n,m;
char a[110][110];
int ans=0;
void dfs(int x,int y){
	a[x][y]='.';
	for(int i=-1;i<=1;i++){
		for(int j=-1;j<=1;j++){
			int nx,ny;
			nx=x+i;
			ny=y+j;
			if(nx>=0&&nx=0&&ny>n>>m;
	for(int i=0;i>a[i];
	for(int i=0;i

题目描述

在峰会期间,武装部队得处于高度戒备。警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机。此外,巡洋船只和舰队将被派去保护海岸线。不幸的是因为种种原因,国防海军部仅有很少的几位军官能指挥大型海战。因此,他们考虑培养一些新的海军指挥官,他们选择了“海战”游戏来帮助学习。

在这个著名的游戏中,在一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。

输入格式

输入文件头一行由用空格隔开的两个整数R和C组成,1<=R,C<=1000,这两个数分别表示游戏棋盘的行数和列数。接下来的R行每行包含C个字符,每个字符可以为“#”,也可为“.”,“#”表示船只的一部分,“.”表示水。

输出格式

为每一个段落输出一行解。如果船的位置放得正确(即棋盘上只存在相互之间不能接触的方形,如果两个“#”号上下相邻或左右相邻却分属两艘不同的船只,则称这两艘船相互接触了)。就输出一段话“There are S ships.”,S表示船只的数量。否则输出“Bad placement.”。

输入输出样例

输入 #1复制

6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#

输出 #1复制

There are 5 ships.
#include 
using namespace std;
int n,m;
char  a[1010][1010];
long long ans;
void dfs(int x,int y){
	a[x][y]='.';
	int dx[4]={-1,0,1,0};
	int dy[4]={0,1,0,-1};
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx<=n&&nx>=0&&ny<=m&&ny>=0&&a[nx][ny]=='#')
		{
			dfs(nx,ny);
		}
	}return;
}
bool hefa(int i,int j){//边界条件的推导呀,然后写成一个函数判断就可以了呀 
	int c=0;
	    if(a[i][j]=='#') c++;
		if(a[i+1][j]=='#') c++;
		if(a[i][j+1]=='#') c++;
		if(a[i+1][j+1]=='#') c++;
		if(c==3) return false;
		return true;
	
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i>a[i][j];
		}
	}
	for(int i=0;i

题目描述

一矩形阵列由数字 00 到 99 组成,数字 11 到 99 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。

输入格式

第一行两个整数代表矩阵大小 nn 和 mm。

接下来 nn 行,每行一个长度为 mm 的只含字符 0 到 9 的字符串,代表这个 n \times mn×m 的矩阵。

输出格式

一行一个整数代表细胞个数。

输入输出样例

输入 #1复制

4 10
0234500067
1034560500
2045600671
0000000089

输出 #1复制

4

说明/提示

数据规模与约定

对于 100\%100% 的数据,保证 1 \le n,m \le 1001≤n,m≤100。

//连通块,皆可 
//dfs
#include 
using namespace std;
int n,m=0;
char a[110][110];
bool used[110][110];//初始为0 
int ans=0;
void dfs(int x,int y){
	used[x][y]=1;
	int dx[4]={-1,0,1,0}; 
	int dy[4]={0,1,0,-1};
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(a[nx][ny]==0||used[nx][ny]==1) continue;
		dfs(nx,ny);
	}
	
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++ ){
			scanf("%1d",&a[i][j]);
			//会出错cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(used[i][j]==0&&a[i][j]!=0){
				dfs(i,j);
        	    ans++; 
			}
		}
	}    
	cout<
//bfs用队列进行维护 ,通常和结构体搭配,记录步数,坐标等 
#include 
using namespace std;
int n,m;
char a[110][110];
bool biaoji[110][110];
int ans=0;
int dx[4]={0,-1,0,1};
int dy[4]={1,0,-1,0};//结构体,以及队列的创建 
struct Point{
	int x;
	int y;
};
queueq;
void bfs(int sx,int sy){
	Point st;//初始化 
	st.x=sx;
	st.y=sy;
	q.push(st);
	biaoji[sx][sy]=1;
	while(!q.empty()){
		Point nw=q.front();
		for(int i=0;i<4;i++){//状态 
			Point nt=nw;
			nt.x+=dx[i];
			nt.y+=dy[i];
			if(a[nt.x][nt.y]==0||biaoji[nt.x][nt.y]==1)continue;//判断合法 
		     q.push(nt);
		     biaoji[nt.x][nt.y]=1;
		}
		q.pop();
	}
}
int main(){
	cin>>n>>m;
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++) 
				scanf("%1d",&a[i][j]);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(biaoji[i][j]==0 && a[i][j]!=0)
				{
				    bfs(i,j);
				    ans++;//若这一连通块没搜过ans++ 
				}
			}
		}
		cout<

练习题阿巴阿巴

D - Oil Deposits

ac代码

#include 
using namespace std;

int n,m;
char a[110][110];
int ans=0;
void dfs(int x,int y){
	a[x][y]='*';
	for(int i=-1;i<=1;i++){
		for(int j=-1;j<=1;j++){
			int nx,ny;
			nx=x+i;
			ny=y+j;
			if(nx>=0&&nx=0&&ny>a[i][j];
		}
	}
	for(int i=0;i

 超空间了

#include 
using namespace std;
int n,m;
char  a[101][101];
int ans=0;
queuehang;
queuelie;
void bfs(int x,int y){
	a[x][y]='*';
	int nx;
	int ny;
	for(int i=-1;i<=1;i++){
		for(int j=-1;j<=1;j++){
			nx=x+i;
			ny=y+j;
			if(nx>=0&&nx=0&&ny>a[i][j];
		}
	}
	for(int i=0;i

 移动

#include
#include
using namespace std;
#include
int x1,y1,x2,y2;
bool book[310][310];
struct data{
	int x;
	int y;
	int step;
};
int bfs();
int main()
{
	int i,j;
	while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)!=EOF)
	{
		memset(book,0,sizeof(book));
		printf("%d\n",bfs());
	}
	return 0;
}
int bfs()
{
	int i;
	int next[8][2]={2,1,1,2,-1,2,-2,1,-2,-1,-1,-2,1,-2,2,-1};
	data A,B;
	queueq;
	A.x=x1;
	A.y=y1;
	A.step=0;
	q.push(A);
	book[A.x][A.y]=1;
	while(!q.empty())
	{
		A=q.front();
		q.pop();
		if(A.x==x2&&A.y==y2)
			return A.step;
		for(i=0;i<8;i++)
		{
			B.x=A.x+next[i][0];
			B.y=A.y+next[i][1];
			B.step=A.step+1;
			if(B.x<0||B.x>300||B.y<0||B.y>300||book[B.x][B.y])
				continue;
			q.push(B);
			book[B.x][B.y]=1;
		}
	} 
}
	

 走迷宫

#include
#include
#include
#include 
using namespace std;

int A[5][5];  
bool visit[5][5]; 
int dx[4]={-1,0,0,1},dy[4]={0,1,-1,0};//走的四个方向 

struct node{  
    int x,y;
    int step; 
    char str[100][100];//记录步数 
};  

//得到此位置的情况 
bool get(int x,int y){  
    if(x<5 && x>=0 && y<5 && y>=0 && !visit[x][y]){
        return true;
    }
    return false;
} 

int BFS(node start){  
    queue Q;

    Q.push(start);

    while(!Q.empty()){
        node tem = Q.front();
        Q.pop();

        if(tem.x==4 && tem.y==4){ 
            for(int i=0 ; i<=tem.step ; i++){
                cout<>A[i][j];
            if(A[i][j] == 1){
                visit[i][j] = true;
            }  
        }
    }
    node start;
    start.x = 0;
    start.y = 0;
    start.step=0;
    strcpy(start.str[start.step],"(0, 0)");
    visit[start.x][start.y]=true;

    BFS(start);   

    
}  

你可能感兴趣的:(c++,图论,算法,深度优先,宽度优先)