25.1.17学习内容

B - 迷宫

Description

给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

Input

第一行为三个正整数N,M,T,分别表示迷宫的长宽和障碍总数。

第二行为四个正整数 SX,SY,FX,FY,SX,SY 代表起点坐标,FX,FY 代表终点坐标。

接下来 T 行,每行两个正整数,表示障碍点的坐标。

Output

输出从起点坐标到终点坐标的方案总数。

Hint

对于100% 的数据,1≤N,M≤5,1≤T≤10,1≤SX,FX≤n,1≤SY,FY≤m。

cpp 复制代码
#include<stdio.h>
#include<string.h>
struct a{
	struct b{
		int x;
		int y;
	}step[100];
}route[5000];
int dfs(int map[][10],int mark[][10],int N,int M,struct a route_temp,int start_x,int start_y,int end_x,int end_y,int *num,int step_num)
{
	route_temp.step[step_num].x=start_x,route_temp.step[step_num].y=start_y,step_num++;
	if(start_x==end_x&&start_y==end_y){
		int x=0;
		for(int i=0,j;i<*num;i++)
		{
			for(j=0;j<step_num;j++)
			{
				if(route_temp.step[j].x==route[i].step[j].x&&route_temp.step[j].y==route[i].step[j].y)continue;
				else break;
			}
			if(j==step_num){
				x=1;
				break;
			}
		}
		if(x!=1)route[(*num)++]=route_temp;
	}
	if(map[start_x+1][start_y]==0&&mark[start_x+1][start_y]==0&&start_x+1<=N){
		mark[start_x+1][start_y]=1;
		dfs(map,mark,N,M,route_temp,start_x+1,start_y,end_x,end_y,num,step_num);
		mark[start_x+1][start_y]=0;
	}
	if(map[start_x-1][start_y]==0&&mark[start_x-1][start_y]==0&&start_x-1>0){
		mark[start_x-1][start_y]=1;
		dfs(map,mark,N,M,route_temp,start_x-1,start_y,end_x,end_y,num,step_num);
		mark[start_x-1][start_y]=0;
	}
	if(map[start_x][start_y+1]==0&&mark[start_x][start_y+1]==0&&start_y+1<=M){
		mark[start_x][start_y+1]=1;
		dfs(map,mark,N,M,route_temp,start_x,start_y+1,end_x,end_y,num,step_num);
		mark[start_x][start_y+1]=0;
	}
	if(map[start_x][start_y-1]==0&&mark[start_x][start_y-1]==0&&start_y-1>0){
		mark[start_x][start_y-1]=1;
		dfs(map,mark,N,M,route_temp,start_x,start_y-1,end_x,end_y,num,step_num);
		mark[start_x][start_y-1]=0;
	}
	return 0;
}
int main()
{
	int N,M,barrier_num,start_x,start_y,end_x,end_y,map[10][10],mark[10][10],num=0;
	struct a route_temp;
	scanf("%d %d %d %d %d %d %d",&N,&M,&barrier_num,&start_x,&start_y,&end_x,&end_y);
	memset(map,0,sizeof(map)),memset(mark,0,sizeof(mark)),memset(route,0,sizeof(route)),memset(route_temp.step,0,sizeof(route_temp.step));
	for(int i=0;i<barrier_num;i++)
	{
		int x_temp,y_temp;
		scanf("%d %d",&x_temp,&y_temp);
		map[x_temp][y_temp]=1,mark[x_temp][y_temp]=1;
	}
	if(N==1&&M==1&&barrier_num==1){
		printf("0");
		return 0;
	}
	mark[start_x][start_y]=1;
	dfs(map,mark,N,M,route_temp,start_x,start_y,end_x,end_y,&num,0);
	/*for(int i=0;i<num;i++)
{
	for(int j=0;;j++)
{
	
	if(route[i].step[j].x==end_x&&route[i].step[j].y==end_y){printf("(%d,%d)",route[i].step[j].x,route[i].step[j].y);
	break;}
	else printf("(%d,%d)->",route[i].step[j].x,route[i].step[j].y);
	}
	printf("\n");
	}*/
	printf("%d",num);
	return 0;
}

C - 马的遍历

Description

有一个 n×m 的棋盘,在某个点(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

Input

输入只有一行四个整数,分别为 n,m,x,y。

Output

一个n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。

Hint

数据规模与约定

对于全部的测试点,保证 1≤x≤n≤400,1≤y≤m≤400。

cpp 复制代码
#include<stdio.h>
#include<string.h>
struct Node{
	int x;
	int y;
}node[160005];
int main()
{
	int n,m,x,y,head=1,tail=2,sum=0;
	scanf("%d %d %d %d",&n,&m,&x,&y);
	int num[n+1][m+1],mark[n+1][m+1],step[8][2]={
  
  {2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
	memset(num,-1,sizeof(num)),memset(mark,0,sizeof(mark));
	node[1].x=x,node[1].y=y,num[x][y]=0,mark[x][y]=1;
	while(head<tail)
	{
		int x_temp,y_temp;
		sum=num[node[head].x][node[head].y];
		for(int i=0;i<8;i++)
		{
			x_temp=node[head].x+step[i][0],y_temp=node[head].y+step[i][1];
			if(x_temp<1||x_temp>n||y_temp<1||y_temp>m||mark[x_temp][y_temp]==1)continue;
			else {
				mark[x_temp][y_temp]=1;
			    num[x_temp][y_temp]=sum+1;
				node[tail].x=x_temp,node[tail].y=y_temp;
				tail++;
			}
		}
		head++;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			printf("%d ",num[i][j]);
		}
		printf("\n");
	}
	return 0;
}

D - 填涂颜色

Description

由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:6×6 的方阵(n=6),涂色前和涂色后的方阵如下:

如果从某个 0 出发,只向上下左右 4 个方向移动且仅经过其他 0 的情况下,无法到达方阵的边界,就认为这个 0 在闭合圈内 。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 0 是连通的(两两之间可以相互到达)。

复制代码
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1

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

Input

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

接下来 n 行,由 0 和 1 组成的 n×n 的方阵。

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

Output

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

Hint

对于 100% 的数据,1≤n≤30。
深度算法(时间超限):

cpp 复制代码
#include<stdio.h>
#include<string.h>
int dfs(int map[][31],int mark[][31],int map_temp[][31],int *n,int a,int x,int y)
{
	if(x==0||x==a-1||y==0||y==a-1||*n==1)*n=1;
	if(map[x+1][y]!=0&&map[x-1][y]!=0&&map[x][y+1]!=0&&map[x][y-1]!=0)mark[x][y]=2,map[x][y]=2;
	if(map[x+1][y]==0&&mark[x+1][y]!=1){
		mark[x+1][y]=1;
		dfs(map,mark,map_temp,n,a,x+1,y);
		if(*n==1)return -1;
		map_temp[x+1][y]=2;
		mark[x+1][y]=0;
	}
	if(map[x-1][y]==0&&mark[x-1][y]!=1){
		mark[x-1][y]=1;
		dfs(map,mark,map_temp,n,a,x-1,y);
		if(*n==1)return -1;
		map_temp[x-1][y]=2;
		mark[x-1][y]=0;
	}
	if(map[x][y+1]==0&&mark[x][y+1]!=1){
		mark[x][y+1]=1;
		dfs(map,mark,map_temp,n,a,x,y+1);
		if(*n==1)return -1;
		map_temp[x][y+1]=2;
		mark[x][y+1]=0;
	}
	if(map[x][y-1]==0&&mark[x][y-1]!=1){
		mark[x][y-1]=1;
		dfs(map,mark,map_temp,n,a,x,y-1);
		if(*n==1)return -1;
		map_temp[x][y-1]=2;
		mark[x][y-1]=0;
	}
	return 1;
}
int main()
{
	int a,map[31][31],mark[31][31],map_temp[31][31];
	memset(mark,0,sizeof(mark));
	scanf("%d",&a);
	for(int i=0;i<a;i++)
	{
		for(int j=0;j<a;j++)
		{
			scanf("%d",&map[i][j]);
			if(map[i][j]!=0)mark[i][j]=1;
		}
	}
	for(int i=1;i<a-1;i++)
	{
		for(int j=1;j<a-1;j++)
		{
			memset(map_temp,0,sizeof(map_temp));
			if(map[i][j]==0){
				int n=0;
				dfs(map,mark,map_temp,&n,a,i,j);
				if(n==0){
					for(int k=0;k<a;k++)
					{
						for(int z=0;z<a;z++)
						{
							if(map_temp[k][z]==2)map[k][z]=2,mark[k][z]=1;
						}
					}
				}
			}
		}
	}
	for(int i=0;i<a;i++)
	{
		for(int j=0;j<a;j++)
		{
			printf("%d ",map[i][j]);
		}
		printf("\n");
	}
	return 0;
}

广度算法:

cpp 复制代码
#include<stdio.h>
#include<string.h>
struct Node{
	int x;
	int y;
};
void bfs(int map[][31],int mark[][31],int n,int x,int y)
{
	struct Node node[1000];
	int map_temp[31][31],mark_temp[31][31];
	memset(node,0,sizeof(node)),memset(map_temp,0,sizeof(map_temp)),memset(mark_temp,0,sizeof(mark_temp));
	memcpy(mark_temp, mark, sizeof(mark_temp));
	int o=0,head=0,tail=1,range[4][2]={
  
  {1,0},{0,1},{-1,0},{0,-1}};
	node[head].x=x,node[head].y=y;
	map_temp[x][y]=2,mark_temp[x][y]=1;
	while(head<tail)
	{
		int temp_x,temp_y;
		for(int i=0;i<4;i++)
		{
			temp_x=node[head].x+range[i][0],temp_y=node[head].y+range[i][1];
			if((temp_x==0||temp_x==n-1||temp_y==0||temp_y==n-1)&&mark_temp[temp_x][temp_y]==0)o=1;
			if(temp_x>0&&temp_y>0&&temp_x<n-1&&temp_y<n-1&&mark_temp[temp_x][temp_y]==0){
				node[tail].x=temp_x,node[tail].y=temp_y;
				map_temp[temp_x][temp_y]=2,mark_temp[temp_x][temp_y]=1;
				tail++;
			}
		}
		head++;
	}
	if(o==0){
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(map_temp[i][j]==2){
					map[i][j]=2,mark[i][j]=1;
				}
			}
		}
	}
	else {//回溯
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(map_temp[i][j]==2){
					mark[i][j]=-1;
				}
			}
		}
	}
}
int main()
{
	int map[31][31],mark[31][31],n;
	memset(mark,0,sizeof(mark));
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			scanf("%d",&map[i][j]);
			if(map[i][j]==1)mark[i][j]=1;
		}
	}
	for(int i=1;i<n-1;i++)
	{
		for(int j=1;j<n-1;j++)
		{
			if(map[i][j]==0&&mark[i][j]==0)bfs(map,mark,n,i,j);
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			printf("%d ",map[i][j]);
		}
		printf("\n");
	}
	return 0;
}

E - Lake Counting S

Description 描述

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.
由于最近的降雨,水汇集在农民约翰的田地中的各个地方,其由N X M(1< = N <= 100; 1< = M <= 100)正方形的矩形表示。每一个方格都包含水("W")或旱地(".")。农夫约翰想弄清楚他的田地里形成了多少个池塘。池塘是一组相连的正方形,其中有水,其中一个正方形被认为与所有八个相邻的正方形相邻。给出一张农场主约翰的田地图,确定他有多少个池塘。

Input 输入

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个字符,表示Farmer John的字段的一行。每个字符都是"W"或"."。字符之间没有空格。

Output 输出

Line 1: The number of ponds in Farmer John's field.
第1行:农夫约翰田地里的池塘数。

Hint 提示

OUTPUT DETAILS: There are three ponds: one in the upper left, one in the lower left, and one along the right side.
输出池:有三个池:一个在左上角,一个在左下角,一个沿沿着。

cpp 复制代码
#include<stdio.h>
#include<string.h>
struct Node{
	int x;
	int y;
};
void bfs(char map[][100],int mark[][100],int a,int b,int start_x,int start_y)
{
    struct Node node[10000];
	memset(node,0,sizeof(node));
	int head=0,tail=1,range[8][2]={
    
    {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
	node[0].x=start_x,node[0].y=start_y;
	mark[start_x][start_y]=1,map[start_x][start_y]='\0';
	while(head<tail)
	{
		int temp_x,temp_y;
		for(int i=0;i<8;i++)
		{
			temp_x=node[head].x+range[i][0],temp_y=node[head].y+range[i][1];
			if(temp_x>=a||temp_y>=b||temp_x<0||temp_y<0||mark[temp_x][temp_y]!=0)continue;
			if(map[temp_x][temp_y]=='W'){
				node[tail].x=temp_x,node[tail].y=temp_y;
				map[temp_x][temp_y]='\0',mark[temp_x][temp_y]=1;
				tail++;
			}
		}
		head++;
	}
}
int main()
{
	int a,b,num=0,mark[100][100];
	char map[100][100];
	scanf("%d %d",&a,&b);
	for(int i=0;i<a;i++)
	{
		scanf("%s",map[i]);
	}
	memset(mark,0,sizeof(mark));
	for(int i=0;i<a;i++)
	{
		for(int j=0;j<b;j++)
		{
			if(map[i][j]=='W'&&mark[i][j]==0){
				bfs(map,mark,a,b,i,j);
				num++;
			}
		}
	}
	printf("%d",num);
	return 0;
}
相关推荐
西岸行者7 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码7 天前
嵌入式学习路线
学习
毛小茛7 天前
计算机系统概论——校验码
学习
babe小鑫7 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms7 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下7 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。7 天前
2026.2.25监控学习
学习
im_AMBER7 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J7 天前
从“Hello World“ 开始 C++
c语言·c++·学习