热身赛补题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<iostream>
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;

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值