Eight Digits (A*)

Insert picture description here

Idea: This question can be written directly in BFS. The A* used here. The eight-digit number has a property that there is no solution if and only when the inverse ordinal number pair is odd. Use this property to judge the unsolvable situation, and then write A*, Here we have to look at the heuristic function f(x), f(x) is the distance to the final state. In this question, we can find that the current direction of each count to the final state can only be left and right or move up the line, so at least each Count the distance to Manhattan in the final state. We know that the rest of the heuristic function is to write the shortest path for this problem, use unordered_map to record the distance and status, and also record the path at the time.

#pragma GCC optimize(2)
#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
const int mod=1e9+7;
const int N=2e5+5;
const int inf=0x7f7f7f7f;

int gcd(int a,int b)
{
    
    
    return b==0?a:gcd(b,a%b);
}
 
ll lcm(ll a,ll b)
{
    
    
    return a*(b/gcd(a,b));
}
 
template <class T>
void read(T &x)
{
    
    
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    
    
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
         write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    
    
    ll res=1%p;
    while(b)
    {
    
    
        if(b&1)
            res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}
int dir[4][2]={
    
    {
    
    -1,0},{
    
    1,0},{
    
    0,-1},{
    
    0,1}}; 
string ed="12345678x";
char op[4]={
    
    'u','d','l','r'};
int f(string s)
{
    
    
    int res=0;
    for(int i=0;i<s.size();i++)
    {
    
    
        if(s[i]!='x'){
    
    
            int t=s[i]-'1';
           res+=abs(i/3-t/3)+abs(i%3-t%3);
        }
    }
    return res;
}
string bfs(string start)
{
    
    
    unordered_map<string,int> vis,dis;
    unordered_map<string,pair<string,char>>pre;
    priority_queue<pair<int,string>,vector<pair<int,string>>,greater<pair<int,string>>> heap;
    dis[start]=0;
    heap.push({
    
    f(start),start});
    while(heap.size())
    {
    
    
        auto now=heap.top();heap.pop();
        string state=now.second;
        int step=dis[state];
        if(state==ed)break;
        if(vis[state])continue;
        vis[state]=1;
        int x=state.find('x',0)/3;
        
        int y=state.find('x',0)%3;
     
        string old=state;
        for(int i=0;i<4;i++)
        {
    
    
            int xx=x+dir[i][0];
            int yy=y+dir[i][1];
            if(xx<0||xx>=3||yy<0||yy>=3)continue;
          
            swap(state[x*3+y],state[xx*3+yy]);
            if(!dis.count(state)||dis[state]>step+1)
            {
    
    
                dis[state]=step+1;
                pre[state]={
    
    old,op[i]};
                heap.push({
    
    f(state)+dis[state],state});

            }
            swap(state[x*3+y],state[xx*3+yy]);

        }

    }
    string ans;
    while(ed!=start)
    {
    
    
        ans+=pre[ed].second;
        ed=pre[ed].first;
    }
    reverse(ans.begin(),ans.end());
    return ans;


}
int main()
{
    
    
    string s1,s2,c;
    while(cin>>c){
    
    
        s1+=c;
        if(c!="x") s2+=c;
    }
    int cnt=0;
    for(int i=0;i<s2.size();i++)
     for(int j=i+1;j<s2.size();j++)
       if(s2[i]>s2[j]) cnt++;
       if(cnt&1)
       puts("unsolvable");
       else
       cout<<bfs(s1)<<endl;
       

   
      
   return 0;

}


Guess you like

Origin blog.csdn.net/qq_43619680/article/details/110942956