0
点赞
收藏
分享

微信扫一扫

1.9.每日总计

奋斗De奶爸 2022-01-09 阅读 52
c语言

上午:

dfs

题目描述

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.

解题思路:先找到一个起点‘W’,然后进行dfs,走过的路径赋值为‘.’,并且有上下左右、左上、左下、右上、右下这几个方向,之后判断附近是否有‘W’

代码实现:

#include<stdio.h>	
int n,m;
char a[101][101];//创建地图 
int next[9][2]={{-1,-1},{-1,0},{-1,1},{0,0},{0,1},{0,-1},{1,-1},{1,0},{1,1}};//向上下左右方向移动,包括左上右下 
void dfs(int x,int y)
{
	a[x][y]='.';//将走过的地方做标记 
	for(int i=0;i<9;i++)
	{
		int xx=x+next[i][0];
		int yy=y+next[i][1];
		if(xx>=0&&yy>=0&&xx<=n&&yy<=m&&a[xx][yy]=='W')
		dfs(xx,yy);
	}
	return;
}
int main()
{
	int sum=0;//计数 
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	scanf("%s",a[i]);//输入地图 
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(a[i][j]=='W')//找到W所在地 
			{
			dfs(i,j);
		   sum++;
		}
		
		}
	}
	printf("%d",sum);
}

 

题目描述

给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用*代替,以突出显示单词。例如:

输入:
    8                     输出:
    qyizhong              *yizhong
    gydthkjy              gy******
    nwidghji              n*i*****
    orbzsfgz              o**z****
    hhgrhwth              h***h***
    zzzzzozo              z****o**
    iwdfrgng              i*****n*
    yyyygggg              y******g

输入格式

第一行输入一个数nn。(7 \le n \le 1007≤n≤100)。

第二行开始输入n \times nn×n的字母矩阵。

输出格式

突出显示单词的n \times nn×n矩阵。

输入输出样例

输入 #1复制

7
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa

输出 #1复制

*******
*******
*******
*******
*******
*******
*******

输入 #2复制

8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg

输出 #2复制

*yizhong
gy******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

 思路:同上题一样先找到起始点‘y’,这个题需要‘yizhong’是在同一方向上的(即上下左右、左上、右下等),而且每次移动需要比较是否符合‘yizhong’的顺序,如果满足,另起一个数组来赋值,将满足条件的位置标记,最后输出时判断是否满足条件,满足输出,不满足输出‘*’;

代码实现:

#include<stdio.h>
int n;
char a[101][101];
int c[101][101];
char b[]="yizhong";
int next[9][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,0},{0,1},{1,-1},{1,0},{1,1}};//上下左右移动 
void dfs(int l,int m)//dfs 
{
	for(int i=0;i<9;i++)
	{
		int xx=l,yy=m;
		int pd=1;
		for(int j=0;j<6;j++)//朝一个方向移动6次 
		 {
		  xx+=+next[i][0];
		  yy+=+next[i][1];
		 if(xx<0||yy<0||xx>n||yy>n)//没有超出边界 
		 {
		 pd=0;
		 break;
	}
		 if(b[j+1]!=a[xx][yy])//移动的位置上的字母与b数组中的字母相同 
		 pd=0;
	}
	if(pd==0)
	continue;
	else
	{
		xx=l,yy=m;
		c[xx][yy]=1;//将第一个字母'y'赋值 
	for(int j=0;j<6;j++)
	{    
		 xx+=next[i][0];
	     yy+=next[i][1];
		c[xx][yy]=1;//将走过的路径赋值,表示已走过 
	}
}
}
return;
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%s",a[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
		if(a[i][j]=='y')//找到'y' 
		dfs(i,j);
	}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(c[i][j]==1)
			printf("%c",a[i][j]);
			else
			printf("*");
		}
		printf("\n");
	}
}

 下午:

重新思考了‘填涂颜色’问题,发现了之前存在的bug。

题目描述

由数字00组成的方阵中,有一任意形状闭合圈,闭合圈由数字11构成,围圈时只走上下左右44个方向。现要求把闭合圈内的所有空间都填写成22.例如:6 \times 66×6的方阵(n=6n=6),涂色前和涂色后的方阵如下:

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

输入格式

每组测试数据第一行一个整数n(1 \le n \le 30)n(1≤n≤30)

接下来nn行,由00和11组成的n \times nn×n的方阵。

方阵内只有一个闭合圈,圈内至少有一个00。

//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)

输出格式

已经填好数字22的完整方阵。

输入输出样例

输入 #1复制

6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出 #1复制

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

bug所在:dfs中判断条件的限制大小,这里要考率将范围扩大一个

如数据

6

0 0 1 1 1 1

1 1 0 0 0 1

1 1 1 1 1 1

1 1 0 0 0 1

1 1 0 0 0 1 

1 1 0 0 0 1

不超出地图范围情况下,下端的0不会遍历,这样它也会是2,但我们要考虑的只是被一包围的0,所以应该将范围开大一个,即x>k+1同时y>k+1,它会从地图下端向上遍历0,。

同时x<0,y<0,避免第一行第一列全为1,而不进行遍历的情况。

代码:

#include<stdio.h>
int map[32][32];
int a[32][32];
int xx,yy;
int k;
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//上下左右移动 
void dfs(int x,int y)//dfs 
{
	if(x<0||y<0||x>k+1||y>k+1||map[x][y]!=0||a[x][y]!=0)//注意边界,需要将范围扩大一个 
	return;
	else
	{
	a[x][y]=1;//将走过的路径赋值,表示已走过	
	for(int i=0;i<4;i++)
	{
		xx=x+next[i][0];
		yy=y+next[i][1];
		dfs(xx,yy);
	}
}
}
int main()
{
	scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		for(int j=1;j<=k;j++)
		scanf("%d",&map[i][j]); //地图 
	}
	dfs(0,0);//从0开始 
for(int i=1;i<=k;i++)
	{
		for(int j=1;j<=k;j++)
		{
		if(a[i][j]==0&&map[i][j]==0)//如果没有走过且地图上的值为0
		{
	     	printf("2");
			printf(" ");
	}
			else
			{
		printf("%d",map[i][j]);
		printf(" ");
	}
	}
		printf("\n");
	}
}

 然后我又学习了c++的一些基础

如:

模板:

#include<iostream>
using namespace std
int main()
{
   cin>>
   cout<<"";
    return 0;
}

 

今日总结:

 dfs现在知道如何运用了,但是bfs还没完全学会(主要是别人的csdn中直接运用函数quene等)

同时自己摸索知道如何朝八个方向移动。

今天的收获还行。

今日学习时长:9小时51分钟。

举报

相关推荐

0 条评论