poj2488

8 篇文章 0 订阅
涉及算法:dfs
题目大意:给定一个p行q列的棋盘,问是否能不重复的走过棋盘的每一格,若能则按字典顺序输出路径

注意:我们只需要在搜索时按字典顺序搜索,就能按字典顺序输出路径

代码如下:
方式一:
package com.solo.dfs;

import java.util.Scanner;

public class Main_2488 {

	static int a,b;//a行,b列
	static int[][] used;
	static Path[] pathGroup;
	static int mStep;//a*b	
	static class Path{
		int x,y;
		Path pre;
		Path(int x,int y,Path pre){
			this.x=x;
			this.y=y;
			this.pre=pre;
		}
	}
	
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		int k=n;
		while(n-->0){
			a=in.nextInt();
			b=in.nextInt();
			
			mStep=a*b;
			used=new int[b][a];
			used[0][0]=1;
			pathGroup=new Path[a*b];
			System.out.println("Scenario #"+(k-n)+":");
			if(!dfs(0, 0, 1,new Path(0, 0, null))){
				System.out.println("impossible");
				System.out.print("\n");
			}else {
				showPath(pathGroup);
			}
		}
	}

	static boolean dfs(int i,int j,int step,Path path){
		if(step==mStep){
			for(int k=0;k<mStep;k++){
				pathGroup[k]=path;
				path=path.pre;
			}
			
			return true;
		}
		int x=0;
		int y=0;
		for(int k=0;k<8;k++){
//为了保证字典顺序,如下的顺序不能打乱
			if(k==0){
				x=i-2;
				y=j-1;
			}else if(k==1){
				x=i-2;
				y=j+1;
			}else if (k==2) {
				x=i-1;
				y=j-2;
			}else if (k==3) {
				x=i-1;
				y=j+2;
			}else if (k==4) {
				x=i+1;
				y=j-2;
			}else if (k==5) {
				x=i+1;
				y=j+2;
			}else if (k==6) {
				x=i+2;
				y=j-1;
			}else if (k==7) {
				x=i+2;
				y=j+1;
			}
			
			if(x<0 || x>=b || y<0 || y>=a || used[x][y]==1) continue;
			used[x][y]=1;
			
			if(dfs(x, y, step+1,new Path(x, y, path))){
				return true;
			}
			used[x][y]=0;
		}
		
		return false;
	}
	
	static void showPath(Path[] paths){
		int x=0;
		int y=0;
		for(int i=mStep-1;i>=0;i--){
			x=paths[i].x; y=paths[i].y;
			System.out.print((char)(x+65)+""+(y+1));
		}
		System.out.println("\n");
	}
}

方式二:
package com.solo.dfs;

import java.util.Scanner;


public class Main_2488_1
{
	static int p;//行
	static int q;//列
	static int d[][]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
	static int vis[][];
	static int path[];//用来记录走过的路径,用个位和十位表示y轴的坐标,用百位和千位表示x的坐标
	public static void main(String[] args)
	{
		Scanner in=new Scanner(System.in);
		int k=in.nextInt();
		int n=k;
		while(k-->0)
		{ 
			p=in.nextInt();
			q=in.nextInt();
			vis=new int[q][p];
			path=new int[p*q+1];
			vis[0][0]=1;
			path[1]=0;
			System.out.println("Scenario #"+(n-k)+":");
			if(!dfs(0, 0, 1))
			{
				System.out.println("impossible");
				System.out.print("\n");
			}
			else
			{
				showPath();
			}
		}
	}
	
	static boolean dfs(int x,int y,int step)
	{
		if(step==p*q)
		{
			return true;
		}
		for(int i=0;i<8;i++)
		{
			int dx=x+d[i][0];
			int dy=y+d[i][1];
			if(dx>=0 && dx<q && dy>=0 && dy<p && vis[dx][dy]==0)
			{
				vis[dx][dy]=1;
				path[step+1]=dx*100+dy;
				if(dfs(dx, dy, step+1))
				{
					return true;
				}
				vis[dx][dy]=0;
			}
			else 
			{
				continue;
			}
		}
		return false;
	}
	
	static void showPath()
	{
		int x=0;
		int y=0;
		for(int i=1;i<=p*q;i++){
			x=path[i]/100; y=path[i]%100;
			System.out.print((char)(x+65)+""+(y+1));
		}
		System.out.println("\n");
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值