上午:
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分钟。