热身赛补题A - Rush Hour Puzzle Gym - 102460A

原题

Rush Hour is a puzzle game invented by Nob Yoshigahara in the 1970s. It is now being
manufactured by ThinkFun. The board is a 6 × 6 grid with grooves in the tiles to allow
vehicles to slide. Cars and trucks are both one square wide, but cars are two squares long and
trucks are three squares long. Vehicles can only be moved forward or backward along a straight
line on the grid. The goal of the game is to get the only red car totally out through the exit
of the board by moving the other vehicles out of its way. Figure 1 gives an example of Rush
Hour puzzle.
We give each vehicle of a puzzle a unique id, numbered from 1 to the number of vehicles, in
which the red car’s id is 1. The board information of a puzzle is represented by a 6 × 6 matrix,
named board matrix. Each entry of a board matrix is the id of the vehicle placed on that
groove, and the entries are filled with 0 if there exists no vehicle on those grooves. The exit
of the board is located at the right end side of the 3rd row. Figure 2 shows the board matrix
corresponding to the puzzle in Figure 1.
Moving a piece (car or truck) by one unit (a groove) is called a step. A puzzle is easy if it
can be solved (the red car totally out through the exit of the board) in no more than 10 steps.
Please write a program to judge whether a puzzle is easy or not.
Input Format
The input contains 6 lines, each line indicates the content (6 integers separated by a blank) of
each row of a board matrix.
Output Format
Output the minimum number of steps for solving the input puzzle if the puzzle is easy, otherwise
output -1.
Technical Specification
• There are at most 10 vehicles on the board for each puzzle.
• Only the red car can be moved out of the board for each puzzle.
Sample Input 1
2 2 0 0 0 7
3 0 0 5 0 7
3 1 1 5 0 7
3 0 0 5 0 0
4 0 0 0 8 8
4 0 6 6 6 0
Sample Output 1
-1
Sample Input 2
0 2 0 6 6 0
0 2 0 0 7 0

题意

移动小车使之从一个固定的出口离开,迭代加深的题,只要判断好,小车的方向,就比较容易了,比赛时卡题意了,没有发现是只能再一个固定的出口离开,另外一个难点在于如何高效的判断小车的方向,利用小车的长度是一种方式,再加上数据范围较小,可以直接暴力去做

代码

#include
using namespace std;
int a[8][8];
int len[12],cnt;
int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool vis[8][8];
bool check(int x,int y){
	return x>=1&&x<=6&&y>=1&&y<=6;
}
int cal(){//估价函数用于计算走出的最小步数
	for(int i=1;i<=6;i++)
		if(a[3][i]==1)
			return 7-i;
	return 0;
}

int dfs(int mxd,int cur){
	int p=cal();
	if(p+cur>mxd){
		return 0;
	}
	if(p==len[1]){
		return 1;
	}
	//如果车长度等于估价函数,代表可以走出去
	for(int i=1;i<=6;i++){
		for(int j=1;j<=6;j++){
			if(a[i][j]){
				int q=a[i][j];
				for(int k=0;k<4;k++){
					int x=i,y=j;

					int ddx=mov[k][0]*(len[q]-1)+x;
					int ddy=mov[k][1]*(len[q]-1)+y;

					int dx=mov[k][0]*len[q]+x;
					int dy=mov[k][1]*len[q]+y;

					if (a[ddx][ddy]==q&&check(dx,dy))
					{
						/* code */
						if(a[dx][dy]==0){
							a[dx][dy]=q;
							a[x][y]=0;
							if(dfs(mxd,cur+1))
								return 1;
						a[x][y]=q;
						a[dx][dy]=0;
						}
					}
					
				}

			}
		}
	}

	return 0;
}
//记录车的长度的函数 
int dfslen(int x,int y){
	int ans=1;
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int xx=x+mov[i][0],yy=y+mov[i][1];
		if(!check(xx,yy)||vis[xx][yy])
			continue;
		if(a[xx][yy]==a[x][y])
			ans+=dfslen(xx,yy);
	}
	return ans;

}
	

int main(){
	for(int i=1; i<=6; i++)
		for(int j=1; j<=6; j++)
			scanf("%d",&a[i][j]),cnt=max(cnt,a[i][j]);//记录车的数量 
	for(int i=1;i<=6;i++)
		for(int j=1;j<=6;j++)
			if(a[i][j]&&!len[a[i][j]])
				len[a[i][j]]=dfslen(i,j);//记录车的长度 
			
	for(int i=1;i<=10;i++){
		if(dfs(i,0)){
			printf("%d\n",i);
			return 0;
		}
	}
	cout<<-1;
	return 0;

}

你可能感兴趣的:(热身赛补题A - Rush Hour Puzzle Gym - 102460A)