uva11198 Dancing Digits

13 篇文章 0 订阅
8 篇文章 0 订阅

简单题,直接暴力,而且不需要太多剪枝就能过。

忘了写insert函数的返回值导致wa一次,怎么感觉oj上的编译器和我电脑上的g++不一样


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define HASHSIZE 40000
#define MAX 50000
using namespace std;

char prime[16]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0};//0 to 15
int input[8],head[HASHSIZE],next[MAX],s[MAX][8],steps[MAX],front,rear,flag,all;

int isprime(int index)
{
    if(index-1>=0&&s[rear][index-1]*s[rear][index]<0&&prime[abs(s[rear][index-1])+abs(s[rear][index])]==1)
        return 1;
    if(index+1<8&&s[rear][index+1]*s[rear][index]<0&&prime[abs(s[rear][index+1])+abs(s[rear][index])]==1)
        return 1;
    return 0;
}

int hash(int cur)
{
    int value=0,i;
    for(i=0;i<8;i++)
        value=(value*10+abs(s[rear][i]))%HASHSIZE;//abs放错了位置
    return value;
}

int insert(int cur)
{
    int hashvalue=hash(cur);
    int u=head[hashvalue];
    while(u!=-1)
    {
        if(memcmp(s[cur],s[u],8*4)==0)
            return 0;
        u=next[u];
    }
    next[cur]=head[hashvalue];
    head[hashvalue]=cur;
    return 1;//返回值忘了写
}

void toget()
{
    int i,j,t,a,b,help;
    for(i=0;i<8;i++)//起始
    {
        for(j=0;j<8;j++)//目标
        {
            if(j==i)
                continue;
            memcpy(s[rear],s[front],8*4);
            help=s[rear][i];
            if(j<i)
            {
                for(t=i;t>=j+1;t--)
                    s[rear][t]=s[rear][t-1];
                s[rear][j]=help;
            }
            else if(j>i)
            {
                for(t=i;t<=j-1;t++)
                    s[rear][t]=s[rear][t+1];
                s[rear][j]=help;
            }
            if(isprime(j))
            {
                if(insert(rear))
                {
                    steps[rear]=steps[front]+1;
                    rear++;
                }
            }
        }
    }
}

void bfs()
{
    int i,j;
    front=0,rear=1,flag=0;
    memcpy(s[front],input,8*4);
    steps[front]=0;
    memset(head,-1,HASHSIZE*4);
    while(front<rear)
    {
        if((abs(s[front][0])==1)&&(abs(s[front][1])==2)&&(abs(s[front][2])==3)&&(abs(s[front][3])==4)&&(abs(s[front][4])==5)&&(abs(s[front][5])==6)&&(abs(s[front][6])==7)&&(abs(s[front][7])==8))
        {
            flag=1;
            all=steps[front];
            break;
        }
        toget();
        front++;
    }
    if(flag==0)
        printf("-1\n");
    else
        printf("%d\n",all);
}

int main()
{
    int i,j,count=1;
    while(scanf("%d",&input[0])&&input[0])
    {
        for(i=1;i<8;i++)
            scanf("%d",&input[i]);
        printf("Case %d: ",count++);
        bfs();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值