hdu1043Eight

//暴力打表搞定

http://acm.hdu.edu.cn/showproblem.php?pid=1043
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct sss
{
 int pre,step;
 int op,pos;
 char s[10];
};
int hash[362888];
sss que[362888];
int nn[10]={1,1,2,6,24,120,720,5040,40320};
char star[10]="123456789";
char res[5]="urld";
int up(char *pre,char *now,int pos)//求得都是相反的,因为反过来输出
{
 if(pos>5) return -1;
 strcpy(now,pre);
 now[pos]=now[pos+3];
 now[pos+3]='9';
 return pos+3;
}
int down(char *pre,char *now,int pos)
{
 if(pos<3) return -1;
 strcpy(now,pre);
 now[pos]=now[pos-3];
 now[pos-3]='9';
 return pos-3;
}
int left(char *pre,char *now,int pos)
{
 if(pos%3==2) return -1;
 strcpy(now,pre);
 now[pos]=now[pos+1];
 now[pos+1]='9';
 return pos+1;
}
int right(char *pre,char *now,int pos)
{
 if(pos%3==0) return -1;
 strcpy(now,pre);
 now[pos]=now[pos-1];
 now[pos-1]='9';
 return pos-1;
}
int (*fun[4])(char *,char *,int)={up,right,left,down};//可以一次调用4个函数
int calhash(char *num)//计算hash表
{
 int i,j,cnt;
 int sum=0;
 for(i=0;i<9;i++)
 {
  cnt=0;
  for(j=0;j<i;j++)
   if(num[j]>num[i]) cnt++;
  sum+=cnt*nn[i];
 }
 return sum;
}
void result(int ihash)//输出结果
{
 int in=hash[ihash];
 while(que[in].op!=-1)
 {
  putchar(res[que[in].op]);
  in=que[in].pre;
 }
}
void init()//标记所有的结果
{
 que[1].op=-1;
 que[1].step=0;
 que[1].pos=8;
 strcpy(que[1].s,star);
 int ihash=calhash(star);
 hash[ihash]=1;
 int i,head=1;
 int tail=2;
 while(head<tail)
 {
  for(i=0;i<4;i++)
  {
   que[tail].pos=(*fun[i])(que[head].s,que[tail].s,que[head].pos);
   if(que[tail].pos==-1) continue;
   ihash=calhash(que[tail].s);
   if(hash[ihash]) continue;
   hash[ihash]=tail;
   que[tail].pre=head;
   que[tail].op=i;
   tail++;
  }
  head++;
 }
}
char a[50],b[20];
int main()
{
 init();
 int i,j,ihash;
 while(gets(a))
 {
  for(i=0,j=0;a[i]&&j<9;i++)
  {
   if(a[i]=='x')
    b[j++]='9';
   else if(a[i]>='0'&&a[i]<='9')
     b[j++]=a[i];
  }
  ihash=calhash(b);
  if(hash[ihash])
   result(ihash);
  else
   printf("unsolvable");
  printf("\n");
 }
 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值