USACO Section 3.2 Magic Squares - 我承认我是瞎混过去的..

   首先题目看清楚.是从1,2,3,4,5,6,7,8到目前状态..然后..我就是很恶心的Hash+暴力BFS了..

   我的Hash很恶心...并且是在WA了几次后修改对的..好邪恶..我觉得好的方法应该是Astar或者更加科学的Hash吧..其实这道题的每个状态是可以明确表示出来的..因为总的状态数也就8!=40320种~感觉好麻烦..我就恶心的Hash了..


Program:

/*  
ID: zzyzzy12   
LANG: C++   
TASK: msquare
*/      
#include<iostream>      
#include<istream>  
#include<stdio.h>      
#include<string.h>      
#include<math.h>      
#include<stack>  
#include<algorithm>      
#include<queue>   
#define oo 2000000000  
#define ll long long   
using namespace std;    
struct node
{
      string ans;
      int a[8];    
}h,k;
queue<node> myqueue;
int i,p,t,goal,g[3][8]={{7,6,5,4,3,2,1,0},{3,0,1,2,5,6,7,4},{0,6,1,3,4,2,5,7}};
bool used[5000001]; 
int getdata(node p)
{
      int i,m=0,k=1; 
      for (i=0;i<8;i++)
      {
          m+=k*p.a[i]; 
          k=(k*17)%387723;
      }
      return m;
}
int main()  
{  
      freopen("msquare.in","r",stdin);    
      freopen("msquare.out","w",stdout);   
      while (!myqueue.empty()) myqueue.pop();
      memset(used,false,sizeof(used));
      for (i=0;i<8;i++) scanf("%d",&h.a[i]);  
      goal=getdata(h);
      for (i=0;i<=8;i++) h.a[i]=i+1;
      h.ans=""; 
      t=getdata(h); myqueue.push(h);
      used[t]=true;
      if (t==goal) k=h; 
      else 
      while (1)
      {
             h=myqueue.front(); 
             myqueue.pop();
             for (p=0;p<3;p++)
             {
                    k.ans=h.ans+char('A'+p); 
                    for (i=0;i<8;i++) k.a[i]=h.a[g[p][i]]; 
                    t=getdata(k); 
                    if (t==goal) break;
                    if (!used[t]) myqueue.push(k);
                    used[t]=true; 
             }        
             if (t==goal) break;             
      }
      p=k.ans.length();
      printf("%d\n",p);;
      for (i=0;i<p;i++)
      {
            printf("%c",k.ans[i]);
            if (i%60==59) printf("\n");
      } 
      printf("\n");
      return 0;     
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值