[Week2 homework] A-Maze, B-Pour Water

A - Maze

Topic:

Dongdong has a map and wants to find the sister paper through the map. The map shows that 0 means you can walk, 1 means you can't walk, the upper left corner is the entrance, and the lower right corner is the sister paper. These two positions are guaranteed to be 0. Now that you know the map, it is not difficult for Dongdong to find sister paper. Please write a program to write the shortest route for Dongdong to find sister paper.

Input

The input is a 5 × 5 two-dimensional array, consisting of only two digits 0 and 1, representing a normal matrix map.

Output

Several lines are output, representing the coordinates of the shortest path from the upper left corner to the lower right corner, in the format shown in the sample. The data is guaranteed to have a unique solution.

Sample Input

0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)

Hint

The coordinates (x, y) indicate the x-th row and y-column, the row and column numbers start from 0, and the upper left corner is used as the origin.
Also note that there should be a space after the comma separating the coordinates in the output.

Ideas and practices:

Since the shortest route is to be calculated, the width-first search is used directly, and all locations on the map are traversed from the upper left corner.
For any position (x, y), if it has not been touched before, update it-make the contact mark (dis two-dimensional array is initially -1 means contact, and dis [x] [ y] Record as the parent node dis + 1), record the parent node (b two-dimensional structure array), and put it in the queue. When the final queue is empty, all the places that can be reached are traversed.
Finally, return the value in the b array at the lower right corner (that is, the parent node of the "sister" position), define the print function to output the path recursively.

to sum up:

A very basic breadth-first search question, without any transformation of thinking, can be completed according to the meaning of the question directly.
It should be noted that the wide search uses the const dx [] and dy [] arrays to achieve "movement" in 4 directions, and the boundary of the if judgment, whether it has been touched (must not be repeated), and whether it cannot be touched (map The 1 in the input cannot go) and the output of the final result uses recursion (a very clever method).

Code:

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
const int n=5;
int a[n][n];
int dis[n][n];
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
struct point{
	int x,y;
	point(){}
	point(int x,int y):x(x),y(y){}
};
point b[n][n];
queue<point> Q;
point bfs(){
	Q.push(point(0,0));
	dis[0][0]=0;
	while(!Q.empty()){
		point now=Q.front();
		Q.pop();
		for(int i=0;i<4;i++){
			int x=now.x+dx[i],y=now.y+dy[i];
			if(x>=0&&x<=n-1&&y>=0&&y<=n-1){
				if(dis[x][y]==-1&&!a[x][y]){
					dis[x][y]=dis[now.x][now.y]+1;
					b[x][y]=now;
					Q.push(point(x,y));
				}
			}
		}
	}
	return b[n-1][n-1];
}

void print(point p){
	if(p.x!=0||p.y!=0){
		print(b[p.x][p.y]);
	}
	cout<<"("<<p.x<<", "<<p.y<<")"<<endl;
}

int main(){
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cin>>a[i][j];
	memset(dis,-1,sizeof(dis));
	point res=bfs();
	print(res);
	cout<<"(4, 4)"<<endl;
	return 0;
} 

B - For Water

topic:

Pour water problem "fill A" means to fill the A cup, "empty A" means to empty the A cup, "pour AB" means to pour A's water into the B cup and empty the B cup or A.

Input

The input contains multiple sets of data. Each group of data input A, B, C data range 0 <A <= B, C <= B <= 1000, A and B are relatively prime.

Output

The output of your program will consist of a series of instructions. These output lines will cause any tank to contain exactly C units of water. The output of the last line of each set of data should be "success". The output line starts at column 1, and there should be no blank lines or any trailing spaces.

Sample Input

2 7 5
2 7 4

Sample Output

fill B
pour B A
success 
fill A
pour A B
fill A
pour A B
success

Notes

If your output is different from the Sample Output, it doesn't matter. The answer to a certain "AB C" question is multi-solution. You cannot judge the correctness of your program by standard text comparison. So in this question, the SPJ (Special Judge) program determines whether the code you wrote is correct.

Ideas and practices:

Water pouring is a kind of hidden graph problem. It doesn't seem to have much relation with graphs, but it can be abstracted into graphs and use breadth-first search to find the optimal solution.
Abstract the two cups in the question and define them as the structure beizi, as each node in the figure, including the amount of water in the A and B cups and a field indicating where this node comes from (in order to deal with the output required by the problem , The initial node does not need this field). The solution is similar to the solution in Problem A, except that the movement of each node and the judgment of reaching the target node need to be defined by themselves.
Defined in beizi: full A cup, full B cup, empty A cup, empty B cup, A inverted B, B inverted A-these 6 figures can be moved in a specific direction. In addition, the less than sign of the beizi class is reloaded, the purpose is to use map to establish 2 maps: isFound-whether the node has already appeared (do not repeat the search in wide search) and father-the parent node of the node (in order to restore Shortest path).
In the wide search process, for each node taken from the queue, it must check whether it can join the queue in its six directions. To simplify the code, you can write the inspection process as a separate function.
Finally, if the amount of water in one of the two cups in the extracted node is the target amount of water, the path (joint field) can be output recursively.

to sum up:

As long as the hidden graph problem can abstract the original problem into a graph problem (mainly node transfer direction, target node determination, etc.), it can be applied to breadth-first search solutions.

Code:

#include <iostream>
#include <queue>
#include <map>
#include <string>
#include <string.h>
using namespace std;
int A,B,C;
struct beizi{
	int a,b;
	string c;
	beizi(){}
	beizi(int _a,int _b):a(_a),b(_b){}
	beizi(int _a,int _b,string _c):a(_a),b(_b),c(_c){}
	bool operator<(const beizi& temp)const{
		if(a!=temp.a) return a<temp.a;
		return b<temp.b;
	}
	bool operator==(const beizi& temp)const{
		return a==temp.a&&b==temp.b;
	}
	beizi fillA(){
		return beizi(A,b,"fill A");
	}
	beizi fillB(){
		return beizi(a,B,"fill B");
	}
	beizi emptyA(){
		return beizi(0,b,"empty A");
	}
	beizi emptyB(){
		return beizi(a,0,"empty B");
	}
	beizi pourAtoB(){
		return (a+b>B)?beizi(a+b-B,B,"pour A B"):beizi(0,a+b,"pour A B");
	}
	beizi pourBtoA(){
		return (a+b>A)?beizi(A,a+b-A,"pour B A"):beizi(a+b,0,"pour B A");
	}
};
queue<beizi> Q;
map<beizi,bool> isFound;
map<beizi,beizi> father;

bool check(beizi child,beizi now){
	if(isFound[child]==0){
		isFound[child]=1;
		father[child]=now;
		Q.push(child);
	}
}

void print(beizi now){
	if(now==beizi(0,0)) return;
	print(father[now]);
	cout<<now.c<<endl;
}

void bfs(){
	beizi now(0,0);
	Q.push(now);
	isFound[now]=1;
	while(!Q.empty()){
		now=Q.front();
		Q.pop();
		if(now.a==C||now.b==C){
			print(now);
			return;  //找到目标 
		}
		check(now.emptyA(),now);
		check(now.emptyB(),now);
		check(now.fillA(),now);
		check(now.fillB(),now);
		check(now.pourAtoB(),now);
		check(now.pourBtoA(),now);
	}
	return;
}

int main(){
	while(cin>>A>>B>>C){
		isFound.clear();
		father.clear();
		while(!Q.empty()) Q.pop();
		bfs();
		cout<<"success"<<endl;
	} 
	return 0;
} 
Published 10 original articles · Likes0 · Visits 231

Guess you like

Origin blog.csdn.net/weixin_44898140/article/details/104594836