UVA 11198 Dancing Digits

本文详细介绍了如何使用隐式图搜索算法解决UVA_11198数独问题。通过将数值和符号分开存储,并进行广搜遍历,最终找到了数独的解。代码实现简洁高效,适用于类似问题的求解。

UVA_11198

    这个题目是个隐式图搜索的题目,可以把数值和符号分别存在两个数组里面,然后进行广搜即可。

#include<stdio.h>
#include
<string.h>
int st[50000][8],sign[50000][8],dis[50000];
int head[1000003],next[50000];
int target[8]={1,2,3,4,5,6,7,8};
int isprime(int n)
{
int i;
for(i=2;i<n;i++)
if(n%i==0)
return 0;
return 1;
}
int hash(int *A)
{
int i,v=0;
for(i=0;i<8;i++)
v
=10*v+A[i];
return v%1000003;
}
int insert(int s)
{
int i,h;
h
=hash(st[s]);
for(i=head[h];i!=-1;i=next[i])
if(memcmp(st[i],st[s],sizeof(st[i]))==0)
break;
if(i==-1)
{
next[s]
=head[h];
head[h]
=s;
return 1;
}
else
return 0;
}
int main()
{
int i,j,k,p,q,front,rear,t;
t
=0;
while(1)
{
scanf(
"%d",&st[0][0]);
if(st[0][0]==0)
break;
if(st[0][0]<0)
{
st[
0][0]=-st[0][0];
sign[
0][0]=0;
}
else
sign[
0][0]=1;
for(i=1;i<8;i++)
{
scanf(
"%d",&st[0][i]);
if(st[0][i]<0)
{
st[
0][i]=-st[0][i];
sign[
0][i]=0;
}
else
sign[
0][i]=1;
}
front
=rear=0;
memset(head,
-1,sizeof(head));
insert(rear);
dis[rear]
=0;
rear
++;
while(front<rear)
{
if(memcmp(st[front],target,sizeof(target))==0)
break;
for(i=0;i<8;i++)
{
for(j=0;j<i;j++)
if((j!=0&&(sign[front][i]^sign[front][j-1])&&isprime(st[front][i]+st[front][j-1]))
||((sign[front][i]^sign[front][j])&&isprime(st[front][i]+st[front][j])))
{
memcpy(st[rear],st[front],
sizeof(st[rear]));
memcpy(sign[rear],sign[front],
sizeof(sign[rear]));
p
=st[rear][i];
q
=sign[rear][i];
for(k=i;k>j;k--)
{
st[rear][k]
=st[rear][k-1];
sign[rear][k]
=sign[rear][k-1];
}
st[rear][j]
=p;
sign[rear][j]
=q;
if(insert(rear))
{
dis[rear]
=dis[front]+1;
rear
++;
}
}
for(j=i+1;j<8;j++)
if((j!=7&&(sign[front][i]^sign[front][j+1])&&isprime(st[front][i]+st[front][j+1]))
||((sign[front][i]^sign[front][j])&&isprime(st[front][i]+st[front][j])))
{
memcpy(st[rear],st[front],
sizeof(st[rear]));
memcpy(sign[rear],sign[front],
sizeof(sign[rear]));
p
=st[rear][i];
q
=sign[rear][i];
for(k=i;k<j;k++)
{
st[rear][k]
=st[rear][k+1];
sign[rear][k]
=sign[rear][k+1];
}
st[rear][j]
=p;
sign[rear][j]
=q;
if(insert(rear))
{
dis[rear]
=dis[front]+1;
rear
++;
}
}
}
front
++;
}
printf(
"Case %d: ",++t);
if(front!=rear)
printf(
"%d\n",dis[front]);
else
printf(
"-1\n");
}
return 0;
}

  

转载于:https://www.cnblogs.com/staginner/archive/2011/09/18/2180596.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值