zoukankan      html  css  js  c++  java
  • luogu P1379 八数码难题 |状压DP

    题目描述

    在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

    输入格式

    输入初始状态,一行九个数字,空格用0表示

    输出格式

    只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)


    个人感觉,这题可以把9个位置,放在一个数里,也就是9位数,处理倒是方便一点

    往多了算一下O(9*(4^9)),可以接受

    #include<map>
    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int dx[]={-1,0,0,1},dy[]={0,-1,1,0};
    queue<int>q;
    map<int,int>m;
    int n;
    signed main(){
    	cin>>n;
    	q.push(n);
    	m[n]=0;
    	while(q.size()){
    		int u=q.front();
    		int c[3][3],f=0,g=0,n=u;q.pop();
    		if(u==123804765)break;
    		for(int i=2;i>=0;i--)
    		for(int j=2;j>=0;j--){
    			c[i][j]=n%10,n/=10;
    			if(!c[i][j])f=i,g=j;
    		}
    		for(int i=0;i<4;i++){
    			int nx=f+dx[i],ny=g+dy[i],ns=0;
    			if(nx<0||ny<0||nx>2||ny>2)continue;
    			swap(c[nx][ny],c[f][g]);
    			for(int i=0;i<3;i++)
    			for(int j=0;j<3;j++)
    			ns=ns*10+c[i][j];
    			if(!m.count(ns)){
    				m[ns]=m[u]+1;
    				q.push(ns);
    			}
    			swap(c[nx][ny],c[f][g]);
    		}
    	}
    	cout<<m[123804765]<<endl;
    }
    
  • 相关阅读:
    [HNOI/AHOI2018]转盘
    [PKUSC2018]星际穿越
    [PKUSC2018]最大前缀和
    [PKUSC2018]真实排名
    PKUSC2018游记
    [CF843D]Dynamic Shortest Path
    [BZOJ5358]/[HDU6287]口算训练
    [CF160D]Edges in MST
    AGC041D Problem Scores
    BZOJ4079 [WF2014]Pachinko
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/11761928.html
Copyright © 2011-2022 走看看