zoukankan      html  css  js  c++  java
  • hdu 1043 A*

    http://www.cnblogs.com/183zyz/archive/2011/08/12/2135827.html

    #include<stdio.h>
    #define N 363000
    #include<string.h>
    #include<queue>
    using namespace std;
    int visit[N];
    char visit1[N];
    int pre[N],st,a[10],end;
    int dir[9]={1,1,2,6,24,120,720,5040,40320};
    struct node {
     int ma[10];//记录状态
     int ans1;//记录状态值
     int x,f,g;
     bool operator <(const node &a)const {
      return a.f<f;
     }
    };
    int hash(int s[]) {//康拓展开逆序状态值
     int i,j,cnt,sum;
     sum=0;
     for(i=1;i<=9;i++) {
      cnt=0;
      for(j=1;j<i;j++)
       if(s[j]>s[i])cnt++;
       sum+=cnt*dir[i-1];
     }
     return sum;
    }
    int ABS(int x) {
     return x<0?(-x):x;
    }
    int h(int s[]) {//不算x时的曼哈顿距离
     int curx,cury,endx,endy,sum,i,ans;
     sum=0;
     for(i=1;i<=9;i++) {
      if(s[i]==9)continue;
      ans=s[i];
      curx=(i+2)/3;//算出当前的行
      cury=(i-1)%3+1;//算出当前的列
      endx=(ans+2)/3;//算出当前位置的值应该在的行
      endy=(ans-1)%3+1;//算出当前位置的值应该在的列
      sum=sum+ABS(curx-endx)+ABS(cury-endy);//算出距离
     }
     return sum;
    }
    void bfs() {
     int ans,i;
     priority_queue<node>q;
     node cur,next;
     cur.ans1=st=hash(a);//康拓展开查找状态
     visit[cur.ans1]=1;
     if(st==end)
      return;
     for(i=1;i<=9;i++) {//将当前的状态保存下来
      cur.ma[i]=a[i];
      if(a[i]==9)
       cur.x=i;
     }//记录当前的状态
     cur.g=0;//记录深度
     cur.f=h(a);//记录当前的f值
     q.push(cur);//入列
     while(!q.empty()) {
      cur=q.top();//比较f值的大小,选取小的
      q.pop();
      if((cur.x+2)/3!=1) {//向上翻
       next=cur;
       next.x=cur.x-3;//翻转后的位置
       next.ma[cur.x]=next.ma[next.x];//将上方的值存到空格中
       next.ma[next.x]=9;//将上方的值置为空格即‘9’;
       ans=hash(next.ma);//记录翻后的剩余状态
       if(!visit[ans]) {//判断翻转后的状态是否存在
        next.g++;
        next.f=next.g+h(next.ma);////估价函数
        visit[ans]=1;//表示状态值存在
        next.ans1=ans;//将下次状态值记录下来
        pre[ans]=cur.ans1;//将当前状态值记录下来
        visit1[ans]='u';//记录
        if(ans==end)return;
        q.push(next);
       }
      }
       if((cur.x+2)/3!=3) {//向下翻
       next=cur;
       next.x=cur.x+3;
       next.ma[cur.x]=next.ma[next.x];
       next.ma[next.x]=9;
       ans=hash(next.ma);
       if(!visit[ans]) {
        next.g++;
        next.f=next.g+h(next.ma);
        visit[ans]=1;
        next.ans1=ans;
        pre[ans]=cur.ans1;
        visit1[ans]='d';
        if(ans==end) return;
        q.push(next);
       }
      }
        if(cur.x%3!=1) {//向左翻
       next=cur;
       next.x=cur.x-1;
       next.ma[cur.x]=next.ma[next.x];
       next.ma[next.x]=9;
       ans=hash(next.ma);
       if(!visit[ans]) {
        next.g++;
        next.f=next.g+h(next.ma);
        visit[ans]=1;
        next.ans1=ans;
        pre[ans]=cur.ans1;
        visit1[ans]='l';
        if(ans==end)return;
        q.push(next);
       }
      }
         if(cur.x%3!=0) {//向右翻
       next=cur;
       next.x=cur.x+1;
       next.ma[cur.x]=next.ma[next.x];
       next.ma[next.x]=9;
       ans=hash(next.ma);
       if(!visit[ans]) {
        next.g++;
        next.f=next.g+h(next.ma);
        visit[ans]=1;
        next.ans1=ans;
        pre[ans]=cur.ans1;
        visit1[ans]='r';
        if(ans==end)return;
        q.push(next);
       }
      }
     }
    }
    int check(int s[]) {//剪枝判是否有解
     int i,j,cnt=0;
     for(i=1;i<=9;i++) {
      if(s[i]==9)
       continue;
      for(j=1;j<i;j++) {
       if(s[j]==9)
        continue;
       if(s[j]>s[i])
        cnt++;
      }
     }
     return cnt ;
    }
    int main() {
     int i,j,ans;
     char str[50];
     while(gets(str)) {
      ans=0;
      memset(visit,0,sizeof(visit));
      for(i=0;str[i];i++) {
       if(str[i]=='x')
        a[++ans]=9;
       else
        if(str[i]!=' ')
         a[++ans]=str[i]-'0';
      }//处理数据
        end=0;
        ans=check(a);//判断是否有解,即ans值必须是偶数才有结果
        if(ans%2) {
         printf("unsolvable ");
         continue;
        }
        bfs();
        j=0;
        while(end!=st) {//找路径及处理方法
         str[j++]=visit1[end];
         end=pre[end];
        }
        for(i=j-1;i>=0;i--)//输出
         printf("%c",str[i]);
        printf(" ");
        }
     return 0;
    }

  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410973.html
Copyright © 2011-2022 走看看