HDU 1067 Gap bfs,状态表示,vis数组的表示

C++

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <string>
#include <unordered_map>
#include <algorithm>
using namespace std;
string cur(32,1),target(32,1);  //目标状态

struct Node{
    string status;
    int step;
    Node(string s,int step):status(s),step(step){}
    Node(){
        
    }
};

void move(string &str,char ch,int pos){  //将ch放在pos位置上
    int i;
    for(i=0;i<32;i++)
        if(str[i]==ch)
            break;
    if(i!=32){  //若找到了
        str[pos] = ch;
        str[i] = 1;
    }
}

int bfs(){
    unordered_map<string, bool> mp;  //当前状态是否被访问过
    Node now(cur,0),next;
    queue<Node> q;
    q.push(now);
    mp[now.status] = true;
    while(!q.empty()){
        now = q.front();
        q.pop();
        if(now.status == target)  //由于每步操作代价为1,所以不需要pq
            return now.step;
        for(int i=0;i<4;i++){
            for(int j=1;j<8;j++){
                if(now.status[i*8+j]==1 && now.status[i*8+j-1]!=1){
                    //找到一个可以移动的空位,将同suit中的后继放入该位置
                    next = now;
                    move(next.status,now.status[i*8+j-1]+1,i*8+j);
                    if(!mp[next.status]){  //若该状态还没有被访问过
                        mp[next.status] = true;
                        next.step++;
                        q.push(next);
                    }
                }
            }
        }
    }
    return -1;
}

void read(){
    int val;
    for(int i=0;i<4;i++)
        for(int j=1;j<8;j++){
            scanf("%d",&val);
            if(val%10==1){  //若是1开头的,则直接进行移动
                int pos = (val/10-1)*8;  //放在对应行首
                cur[pos] = val;
                cur[i*8+j] = 1;//当前位置为空
            }
            else{   //否则放到相应的位置上
                cur[i*8+j] = val;
            }
        }
}

int main(){
    int T;
    for(int i=0;i<4;i++)
        for(int j=0;j<7;j++)
            target[i*8+j] = (i+1)*10 + (j+1);  //设置为string可以直接比较两个状态
    scanf("%d",&T);
    while(T--){
        read();
        printf("%d\n",bfs());
    }
    return 0;
}

JAVA:

import java.util.*;

public class HDU1067_bfs {
	public static String target;
	
	public static class Node{
		String status;  //当前状态
		int step;		//已经使用的步数
		Node(String status,int step){
			this.status = new String(status);
			this.step = step;
		}
		Node(){
			this.step = 0;
		}
		Node(Node t){
			this.status = new String(t.status);
			this.step = t.step;
		}
	}
	
	public static String change(String str,char ch,int pos) {
		//将ch移动到pos上,pos是一个空位
		int i=0;
		for(i=0;i<32;i++)
			if(str.charAt(i)==ch)
				break;
		char[] arr = str.toCharArray();
		if(i!=32) {  //若找到了该字符
			arr[i] = 0;
			arr[pos] = ch;
		}
		return String.valueOf(arr);
	}
	
	public static int bfs(char[] arr) {
		HashMap<String,Boolean> vis = new HashMap<>();
		String now = String.valueOf(arr);  //初始状态
		Queue<Node> q = new LinkedList<>();
		Node cur,next;
		cur = new Node();
		cur.status = now;   //将初始状态进行赋值
		cur.step = 0;
		vis.put(cur.status, true);
		q.offer(cur);
		while(!q.isEmpty()) {
			cur = q.poll();
			if(cur.status.equals(target))
				return cur.step;
			char[] a = cur.status.toCharArray();
			for(int i=0;i<4;i++) {
				for(int j=1;j<8;j++) {  //寻找可以移动的位置
					if(a[i*8+j]==0 && a[i*8+j-1]!=0) {
						next = new Node(cur);
						char ch = next.status.charAt(i*8+j-1);
						int num = (int)(ch);
						num++;
						ch = (char)(num);
						String str = change(next.status,ch,i*8+j);
						next.status = str;  //变换后的状态
						if(!vis.containsKey(next.status)) {
							vis.put(next.status, true);
							next.step++;
							q.offer(next);
						}
					}
				}
			}
		}
		return -1;
	}
	
	public static void main(String[] args) {	
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		char[] tar = new char[32];
		for(int i=0;i<4;i++) {
			for(int j=0;j<7;j++) {
				int num = (i+1)*10+(j+1);
				char ch = (char)(num);
				tar[i*8+j] = ch;
			}
		}
		target = String.valueOf(tar);
		//target中,非0位置为具体的值,空位为int型的0
		while(T-->0) {
			char[] arr = new char[32];  //读入当前状态
			int val ;
			for(int i=0;i<4;i++) {
				for(int j=1;j<8;j++) {
					val = sc.nextInt();
					char ch = (char)(val);
					if(val%10==1) {
						int pos = (val/10-1)*8;
						arr[pos] = ch;
					}
					else {
						arr[i*8+j] = ch;
					}
				}
			}//读入数据
			int res = bfs(arr);
			System.out.println(res);
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值