uva 704 - Colour Hash

#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#define MAXSTATE 10000000
using namespace std;
typedef int state[24];
state st[MAXSTATE],goal= {0 ,3 ,4, 3 ,0 ,5 ,6, 5, 0 ,1 ,2 ,1, 0, 7,8, 7, 0, 9 ,10, 9 ,0 ,1 ,2 ,1},temp;
int dist[MAXSTATE],back_father[MAXSTATE],father[MAXSTATE],back_path[MAXSTATE],path[MAXSTATE],ans;
map<string,int>vis;
map<string,int>back_vis;
void rotate(int *next, int *origin, int dir)
{
    if(dir==1)  // 左盘顺时针转
    {
        next[0] = origin[10], next[1] = origin[11];
        memcpy(next+2, origin, sizeof(int)*10);  // 大块的,连续数组元素的用memcpy节约时间
        memcpy(next+12, origin+12, sizeof(int)*9);
        next[21]=origin[7], next[22] = origin[8], next[23] = origin[9];
    }
    else if(dir==2)  // 右盘顺时针转
    {
        memcpy(next+12, origin+14, sizeof(int)*10);
        next[22] = origin[12], next[23] = origin[13];
        memcpy(next, origin, sizeof(int)*9);
        next[9] = next[21], next[10] = next[22], next[11] = next[23];
    }
    else if(dir==3)  // 左盘逆时针转
    {
        memcpy(next, origin+2, sizeof(int)*10);
        next[10] = origin[0], next[11] = origin[1];
        memcpy(next+12, origin+12, sizeof(int)*9);
        next[21]=next[9], next[22]=next[10], next[23]=next[11];
    }
    else if(dir==4)  // 右盘逆时针转
    {
        next[12] = origin[22],  next[13] = origin[23];
        memcpy(next+14, origin+12, sizeof(int)*10);
        memcpy(next, origin, sizeof(int)*9);
        next[9] = next[21], next[10] = next[22], next[11] = next[23];
    }
}
string change(state &s)
{
    string str;
    for(int i=0; i<24; i++)
        str+=s[i]+'0';
    return str;
}
void print_back()
{
    string str=change(st[ans]);
    int cur=back_vis[str];
    while(cur)
    {
        printf("%d",back_path[cur]);
        cur=back_father[cur];
    }
}
void print_path(int cur)
{
    if(cur)
    {
        print_path(father[cur]);
        printf("%d",path[cur]);
    }
}
int try_to_insert1(int s)
{
    string str=change(st[s]);
    if(!back_vis[str])
    {
        back_vis[str]=s;
        return 1;
    }
    return 0;
}
int try_to_insert2(int s)
{
    string str=change(st[s]);
    if(!vis[str])
    {
        vis[str]=1;
        return 1;
    }
    return 0;
}
//void change(state &tt,int d) ;
void change (state &,int);
bool frontbfs()
{
    memset(father,0,sizeof(father));
    vis.clear();
    vis[change(temp)]=1;
    int front=0,rear=1;
    memcpy(st[0],temp,sizeof(temp));
    while(front<rear)
    {
        state &s=st[front];
        if(dist[front]>8)
        {
            ++front;
            continue;
        }
        if(memcmp(goal,s,sizeof(s))==0)
        {
            ans=front;
            return false;
        }
        if(back_vis[change(s)])
        {
            ans=front;
            return true;
        }
        for(int d=1; d<=4; d++)
        {
            state &tt=st[rear];
            memcpy(tt,s,sizeof(s));
            //change (tt,d);
            rotate(tt, s, d);
            dist[rear]=dist[front]+1;
            if(try_to_insert2(rear))
            {
                father[rear]=front;
                path[rear]=d;
                rear++;
            }
        }
        front++;
    }
    ans=-1;
    return ans;
}
bool backbfs()
{
    memset(back_father,0,sizeof(back_father));
    dist[0]=dist[1]=0;
    back_vis.clear();
    back_vis[change(goal)]=1;
    int front=0,rear=1;
    memcpy(st[0],goal,sizeof(goal));
    while(front<rear)
    {
        state &s=st[front];
        if(dist[front]>8)
        {
            ++front;
            continue;
        }
        for(int d=1; d<=4; d++)
        {
            state &tt=st[rear];
            memcpy(tt,s,sizeof(s));
             //change (tt,d);
            rotate(tt, s, d);
            dist[rear]=dist[front]+1;
            if(try_to_insert1(rear))
            {
                back_father[rear]=front;
                if(d==1)  back_path[rear]=3;
                else  if(d==2)  back_path[rear]=4;
                else  if(d==3)  back_path[rear]=1;
                else  if(d==4)  back_path[rear]=2;
                rear++;
            }
        }
        front++;
    }
    return false;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int cas;
    backbfs();
    scanf("%d",&cas);
    while(cas--)
    {
        for(int i=0; i<24; i++)
            scanf("%d",&temp[i]);
        if(memcmp(goal,temp,sizeof(temp))==0)
        {
            printf("PUZZLE ALREADY SOLVED\n");
            continue;
        }
        frontbfs();
        if(ans==-1)
        {
            printf("NO SOLUTION WAS FOUND IN 16 STEPS\n");
            continue;
        }
        print_path(ans);
        print_back();
        printf("\n");
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值