洛谷 P6207 [USACO06OCT] Cows on Skates G

洛谷 P6207 [USACO06OCT] Cows on Skates G

Title Portal: P6207Cows on Skates G

Title description

This question uses Special Judge.

Farmer John divided the farm into a matrix of r r rows and c c columns, and found that cows could not pass through some areas. At this moment, Bessie is located in the area with coordinates (1,1)(1,1) and thinks of having dinner in the bullpen with coordinates (r,c)( r , c ). She knew that starting from the area she was in, every time she moved to one of the four adjacent areas, there would always be some paths to the bullpen.
There may be countless kinds of such paths. Please output any one and ensure that the number of moves required does not exceed 100000100000.

Input format

Two integers r and c on the first line .
The next r lines, each line c characters, indicate whether Bessie can pass through the area at the corresponding position. Character may be the only .or *.

  • . Indicates that Bessie can pass through the area.
  • * Indicates that Bessie cannot pass through the area.

Output format

Several lines, each line contains two integers separated by spaces, representing the coordinates of the area that Bessie passes through in turn.

Obviously, the first line of output is 1 1, and the last line is r c.

The areas represented by two adjacent coordinates must be adjacent.

Sample input and output

Enter #1 to copy

5 8
..*...**
*.*.*.**
*...*...
*.*.*.*.
....*.*.

Output #1 copy

1 1
1 2
2 2
3 2
3 3
3 4
2 4
1 4
1 5
1 6
2 6
3 6
3 7
3 8
4 8
5 8

Instructions/tips

[Data range]
For 100% data, 1≤r≤113, 1≤c≤77.

* [Sample description] *

img
The figure is a schematic diagram of the sample output. The answer is not unique.

analysis:

This maze question is a typical search question, because the data range of this question is not large, so I decided to use dfs to do this question.
First, summarize the dfs algorithm. dfs (depth-first traversal search) is a kind of search algorithm. Its traversal process is as follows: first visit the specified initial node; if the adjacent node of the currently visited node has not been visited, choose one to visit; otherwise, return To the nearest node visited; until all the vertices connected to the initial node have been visited; if there are still nodes in the graph (not connected to the initial node) that have not been visited at this time, then select one of the nodes as the initial node and visit , And then repeat the above process; otherwise, the traversal ends.

Let's take a look at a picture to simulate it:

img

First, we randomly select a node as the starting point (take V1 as the starting point as an example)

Take V1 as the starting point (mark), the nodes adjacent to V1 have V2, V3, randomly visit one of them, visit V2 (mark), then V2 has two nodes V4, V5, visit V4 (mark), and V4 has one Node V8, visit V8 (mark), V8 has a node V5, visit V5 (mark), V5 has a node V2, then find that V2 has been marked, then backtrack from V5 to V8, V8 has only one node and is marked , Then trace back from V8 to V4, from V4 to V2, and from V2 to V1. At this time, it is found that V1 has a node V3 that is not marked, then visit V3 (mark), V3 has two nodes V6, V7, visit V6 Mark), V6 has a node V7, visit V7 (mark), the traversal ends.

Access sequence: V1->V2->V4->V8->V5->V3->V6->V7

Attach the dfs template:

void dfs()
{
  if(到达目标状态)
  {
    ...//根据题意输出或者添加其他
    return ;
  }
  //根据题意使用
  /*if(越界或者非合法)
    return ;
  if(特殊状态)//剪枝
    return ;*/
  else
  {
    for(根据题意扩展)//比如有4个方向,则循环4次来搜索
    {
      进行修改操作;//根据题意进行修改
      if(判断是否越界或者非法状态)
      {
        修改操作;//根据题意是否添加
        标记;
        dfs();
        (还原标记即回溯)//根据题意看是否需要
      }
    }
  }
}

Then we look at this question again. We start from the first point and judge whether the next point meets the conditions for walking (not crossing the boundary or in a legal state), if it can go, mark it, and then continue to judge this point, judge Whether its next point satisfies the condition of being able to go, if not, it goes back to the previous point.
Specific operation is as follows:
First, we enter the first two numbers r, c, represents the number of rows of the former, the latter representing the number of characters per line, and each row sequentially input characters (characters can only be .or *). For each character, we use the bool array to make a mark, if the character is ., it is marked as true, otherwise it is marked as false.

In the second step, we do some preparatory work, define a structure array (including abscissa and ordinate), and record the path of point movement. Then use the check() function to judge whether the point is out of bounds or in an illegal state (that is, whether it is marked or the character is *). From the question, the point can only move in four directions (up, down, left, right), we can Define two arrays to represent the abscissa and ordinate (direction array) to modify the direction of movement of each point. (That is, the expansion and modification operations in the dfs template), and then define a variable sum to record the number of steps.

In the third step, we start searching from (1,1). In the dfs function, we first judge whether the point has reached the target point, and if it is satisfied, output and exit. Otherwise, search the surrounding points according to the direction array to determine whether the next point meets check(), if so, mark this point and sum++, otherwise go back to the previous node (ie sum–), Continue to search for the previous point, and then judge again. Until the target point is found.

Code:

#include<bits/stdc++.h>
using namespace std;
int r,c,sum=0;//sum记录步数
bool used[200][200];
char g[200][200];
//定义一个结构体,代表走过的路径
struct ss{
    
    
	int x,y;
};
ss arr[200];
int dx[5]={
    
    0,1,0,-1};//方向数组
int dy[5]={
    
    1,0,-1,0};
inline bool check(int a,int b)//判断是否越界及是否碰到障碍
{
    
    
	if(a<1||a>r||b<1||b>c||used[a][b]==false)
		return false;
	else
		return true;
}
//深搜
void dfs(int a,int b)
{
    
    
	//当走到最后一个点时,输出
	if(a==r&&b==c)
	{
    
    
		for(int i=0;i<sum;i++)
			printf("%d %d\n",arr[i].x,arr[i].y);
		//exit(0);
		return ;
	}
	else
	{
    
    
		int tx,ty;
		for(int i=0;i<4;i++)
		{
    
    
			//对四个方向进行判断
			tx=a+dx[i];
			ty=b+dy[i];
			if(check(tx,ty))
			{
    
    
				arr[sum].x=tx;
				arr[sum].y=ty;
				sum++;//记录走过点的个数
				used[tx][ty]=false;//标记走过的点
				dfs(tx,ty);//找下一个点
				sum--;//回溯
			}
		}
	}
}
int main()
{
    
    
	cin>>r>>c;
	for(int i=1;i<=r;i++)
	{
    
    
		scanf("%s",g[i]+1);
		for(int j=1;j<=c;j++)
		{
    
    
			if(g[i][j]=='*')//判断是否为障碍,然后进行标记
				used[i][j]=false;
			else
				used[i][j]=true;
		}	
	}
	cout<<"1 1"<<endl;//不要忘记输出1 1哦
	dfs(1,1);
	return 0;
}

result:

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_45830165/article/details/109264035