• 八数码问题


    传送门

    //Twenty
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #define INF 0xfffffff
    using namespace std;
    typedef long long LL;
    const int maxn=362880+5;
    int T,a[10],b[10],p[10],f[maxn],d[maxn],g[maxn]; 
    
    void read(int &ret) {
        int f=1; ret=0; char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0'; ret*=f;
    }
    
    struct node {
    	int x;
    	node(int x):x(x){}
        friend bool operator <(const node &A,const node &B) {
    	    return  d[A.x]+g[A.x]>d[B.x]+g[B.x];
    	}
    };
    
    priority_queue<node>que;
    
    int get_rk(int *q) {
       int res=0;
       for(int i=1;i<10;i++) {
       	   int tp=0;
           for(int j=i+1;j<10;j++) 
    	       if(q[j]<q[i]) tp++; 
    	   res+=tp*p[9-i];
       }
       return res+1; 
    }
    
    void get_b(int x) {
    	int tp[10],vis[10]; x--;
    	memset(vis,0,sizeof(vis));
    	memset(tp,0,sizeof(tp));
        for(int i=1;i<9;i++) {
    	    tp[i]=x/p[9-i];
    	    x-=tp[i]*p[9-i];
    	}
    	for(int i=1;i<10;i++) {
    	    int t=tp[i]+1;
    	    for(int j=1;j<10;j++) if(!vis[j]&&((--t)==0)) {
    		    b[i]=j;
    			vis[j]=1;
    			break;
    		}
    	}
    	return;
    }
    
    void cal(int x){
    	if(g[x]!=-1) return;
    	g[x]=0;
        for(int i=1;i<10;i++) {
            int tp=b[i];
            int xx=(b[i]-1)/3,yy=b[i]-xx*3;xx++;
            int o=(i-1)/3,p=i-o*3;
            g[x]+=abs(xx-o-1)+abs(yy-p);
    	}
    	return;
    }
    
    void push(int *q,int pr) {
    	int x=get_rk(q);
    	if(d[pr]+1>=d[x]) return;
    	d[x]=min(d[x],d[pr]+1);	
    	//if(g[x]!=-1) return;
    	cal(x);  
    	que.push(node(x));
    }
    
    int op(int x,int y) {
        return (x-1)*3+y;
    }
    
    void smg(int tpp,int tp,int pr) {
    	swap(b[tpp],b[tp]);
    	push(b,pr);
    	swap(b[tpp],b[tp]);
    }
    
    void work() {
    	int x=get_rk(a);
    	cal(x);  d[x]=0;
    	while(!que.empty()) que.pop();
    	que.push(node(x));
    	int tp;
    	while(!que.empty()) {
    	    node now=que.top();
    	    que.pop();
    		if(now.x==1) break; 
    		get_b(now.x);
    		for(int i=1;i<10;i++) if(b[i]==9) {
    		    tp=i; break;
    		}
    		int xx=(tp-1)/3,yy=tp-xx*3; xx++;
    		if(xx>1) {
    			int tpp=op(xx-1,yy); 
    			smg(tpp,tp,now.x);
    		}
    		if(xx<3) {
    			int tpp=op(xx+1,yy);
    			smg(tpp,tp,now.x);
    		}
    		if(yy>1) {
    			int tpp=op(xx,yy-1);
    			smg(tpp,tp,now.x);			
    		}
    		if(yy<3) {
    			int tpp=op(xx,yy+1);
    			smg(tpp,tp,now.x);
    		}
    	}
    }
    
    void init() {
    	read(T);
    	p[0]=0; p[1]=1;
    	for(int i=2;i<10;i++) p[i]=p[i-1]*i;
    	while(T--) {
    		memset(g,-1,sizeof(g));
    		for(int i=1;i<maxn;i++) d[i]=INF;
    	    for(int i=1;i<10;i++) {
    		    read(a[i]); 
    			if(a[i]==0) a[i]=9;
    		}
    	    work();
    	    if(d[1]!=INF) printf("%d
    ",d[1]);
    	    else printf("No Solution!
    ");
    	}
    }
    
    int main()
    {
    	init();
    	return 0;
    }
    

      

  • 相关阅读:
    冲刺一阶段———个人总结06
    典型用户分析
    冲刺一阶段———个人总结05
    冲刺一阶段———个人总结04
    冲刺一阶段———个人总结03
    冲刺一阶段———个人总结02
    冲刺一阶段———个人总结01
    软件需求分析
    课堂作业——寻找发帖水王
    四则运算网页版
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7725124.html
Copyright © 2020-2023  润新知