zoukankan      html  css  js  c++  java
  • 第二周训练 | 搜索技术 八数码问题和状态图搜索

    八数码求最短步数:

    #include<queue>
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    using namespace std;
    const int LEN = 362880;
    struct node
    {
        int state[9];
        int dis;
    };
    int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
    int visited[LEN]={0};
    int start[9];
    int goal[9];
    long int factory[]={1,1,2,6,24,120,720,5040,40320,362880};
    void swap(int a,int b)
    {
      int c=0;
      c=a;
      a=b;
      b=c; 
    }
    bool Cantor(int str[],int n)
    {
    //    cout<<"hello"<<endl;
        long result = 0;
        for(int i=0;i<n;++i)
        {
            int counted=0;
            for(int j=i+1;j<n;j++)
            {
                if(str[i]>str[j])
                {
                    ++counted;
                }
            }
            result+=counted*factory[n-i-1];
        }
        if(!visited[result])
        {
            visited[result]=1;
            return 1;
        }
        else
        {
            return 0;
        }
         
    }
    int bfs()
    {
        node head;
        memcpy(head.state,start,sizeof(head.state));
        head.dis=0;
        queue<node> q;
        Cantor(head.state,9);
        q.push(head);
         
        while(!q.empty())
        {
            head = q.front();
            q.pop();
            int z;
            for(z = 0;z<9;z++)
            {
                if(head.state[z]==0)
                {
                    break;
                }
            }
            int x = z%3;
            int y = z/3;
    //        printf("head.state[%d]=%d",z,head.state[z]);
            for(int i=0;i<4;++i)
            {
                int newx = x + dir[i][0];
                int newy = y + dir[i][1];
                int nz = newx + 3*newy;
                if(newx>=0&&newx<3&&newy>=0&&newy<3)
                {
                    node newnode;
                    memcpy(&newnode,&head,sizeof(struct node));
                    int c=newnode.state[z];
    				newnode.state[z]=newnode.state[nz];
    				newnode.state[nz]=c;
                    newnode.dis++;
                     
                    if(memcmp(newnode.state,goal,sizeof(goal))==0)
                    {
                        return newnode.dis;
                    }
                    if(Cantor(newnode.state,9))
                    {
                         
                        q.push(newnode);
                    }
                }
            }
             
        }
        return -1;
    }
     
    int main()
    {
        for(int i=0;i<9;++i)
        {
            cin>>start[i];
    //      cout<< start[i];
        }
        cout<<"输入的棋盘:"<<endl;
        for(int i=1;i<=9;++i)
        {
            cout<<start[i-1]<<" ";
            if(i%3==0)cout<<endl;
        }
         
        for(int i=0;i<9;++i) cin>>goal[i];
        cout<<"目标的棋盘:"<<endl;
        for(int i=1;i<=9;++i)
        {
            cout<<goal[i-1]<<" ";
            if(i%3==0)cout<<endl;
        }
        int num = bfs();
        if(num!=-1)
        {
            cout<<num<<endl;
        }
        else
        {
            cout<<"Impossible"<<endl;
        }
        return 0;
    }

    八数码求最短路径:

    /*
    
    2 3 4 1 5 x 7 6 8
    1 2 3 4 6 7 5 8 x
    
    2 3 4 1 5 0 7 6 8
    1 2 3 4 5 6 7 8 0
    ullddrurdllurdruldr
    */
    #include<map>
    #include<queue>
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    using namespace std;
    const int LEN = 362880;
    typedef struct node
    {
    	int state[9];
    	int dis;
    	char road;
    }node;
    int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
    char dir_mark[4]={'l','u','r','d'};
    int visited[LEN]={0};
    int start[9];
    int goal[9];
    long int factory[]={1,1,2,6,24,120,720,5040,40320,362880};
    int flag=1;
    string bigparent="";
    bool Cantor(int str[],int n)
    {
    	long result = 0;
    	for(int i=0;i<n;++i)
    	{
    		int counted=0;
    		for(int j=i+1;j<n;j++)
    		{
    			if(str[i]>str[j])
    			{
    				++counted;
    			}
    		}
    		result+=counted*factory[n-i-1];
    	}
    	if(!visited[result])
    	{
    		visited[result]=1;
    		return 1;
    	}
    	else
    	{
    		return 0;
    	}
    	
    }
    int bfs()
    {
    	node head;
    	memcpy(head.state,start,sizeof(head.state));
    	head.dis=0;
    	head.road='0';
    	queue<node> q;
    	Cantor(head.state,9);
    	q.push(head);
    	map<string,map<string,char> >parent;
    	
    	string str1="";
    	for(int i=0;i<9;++i)
    	{
    		str1+=head.state[i]+'0'; 
    	}
    	parent[str1]["bigparent"]='0';
    				
    	while(!q.empty())
    	{
    		head = q.front();
    		q.pop();
    		int z;
    		for(z = 0;z<9;z++)
    		{
    			if(head.state[z]==0)
    			{
    				break;
    			}
    		}
    		int x = z%3;
    		int y = z/3;
    		for(int i=0;i<4;++i)
    		{
    			int newx = x + dir[i][0];
    			int newy = y + dir[i][1];
    			int nz = newx + 3*newy;
    			if(newx>=0&&newx<3&&newy>=0&&newy<3)
    			{
    				node newnode;
    				
    				memcpy(&newnode,&head,sizeof(struct node));
    				int c=newnode.state[z];
    				newnode.state[z]=newnode.state[nz];
    				newnode.state[nz]=c;
    				
    				//创建一个parent数组记录个节点的父节点 
    				string str1="";
    				string str2="";
    				for(int i=0;i<9;++i)
    				{
    					str1+=newnode.state[i]+'0';
    					str2+=head.state[i]+'0'; 
    				}
    				parent[str1][str2]=dir_mark[i];
    //				cout<<"	parent["<<str1<<"]["<<str2<<"]="<<parent[str1][str2]<<endl; 
    
    
    				newnode.dis++;
    				if(memcmp(newnode.state,goal,sizeof(goal))==0)
    				{
    					string rest="",child="",littleparent="";
    					for(int i=0;i<9;++i)
    					{
    						child+=newnode.state[i]+'0'; 
    					}
    				    while(1)
    				    {
    				    	cout<<"parent["<<child<<"]["<<littleparent<<"]="<<parent[child][littleparent]<<endl;
    				    	rest+=parent[child];
    				    	child=littleparent;
    				    	if(littleparent==bigparent)break;
    					}
    					cout<<rest;
    					flag=0;
    					return newnode.dis;
    				}
    				if(Cantor(newnode.state,9))
    				{		
    				  
    					q.push(newnode);
    					
    				}
    			}
    		}
    		
    	}
    	return -1;
    }
    
    int main()
    {
    	
    	for(int i=0;i<9;++i) 
    	{
    		char temp;
    		cin>>temp;
    		bigparent+=temp;
    		if(temp=='x')
    		{
    			start[i]=0;
    		}
    		else
    		{
    			start[i]=temp-'0';
    		}
    //		cout<< start[i];
    	}
    	cout<<"输入的棋盘:"<<endl;
    	for(int i=1;i<=9;++i) 
    	{
    		cout<<start[i-1]<<" ";
    		if(i%3==0)cout<<endl;
    	}
    	
    	for(int i=0;i<9;++i)
    	{
    		char temp;
    		 cin>>temp;
    		 if(temp=='x')
    		{
    			goal[i]=0;
    		}
    		else
    		{
    			goal[i]=temp-'0';
    		}
    	}
    	
    	cout<<"目标的棋盘:"<<endl;
    	for(int i=1;i<=9;++i) 
    	{
    		cout<<goal[i-1]<<" ";
    		if(i%3==0)cout<<endl;
    	}
    	
    	bfs();
    	if(flag)
    	{
    		cout<<"unsolvable"<<endl;
    	}
    
    	return 0;
     } 
    

      

      

      

  • 相关阅读:
    踩坑:windows系统下,nodejs版本管理器无法使用n来管理
    华为,小米部分机型微信浏览器rem不适配的解决方案
    百度地图滚轮缩放时产生位置偏移 问题
    baidu-aip-SDK node.js 身份证识别
    iconfont 怎么在项目中使用图标库
    前端实用功能:选项卡切换
    input复选框操作的部分高频率使用代码
    HTML标签的命名/CSS标准化命名大全
    如何在网页中设置一个定时器计算时间?
    H5JS二维动画制作!two.js的基本操作class2
  • 原文地址:https://www.cnblogs.com/chrysanthemum/p/11815838.html
Copyright © 2011-2022 走看看