您的位置:首页 > 产品设计 > UI/UE

UESTC_魔法少女小蟹 CDOJ 710

2015-04-29 23:49 323 查看
小蟹是一名魔法少女,能熟练的施放很多魔法。

有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数。

小蟹翻了下魔法书,发现她有以下6种魔法:

将当前魔杖指向的数字与最左端的一个数字调换位置。

将当前魔杖指向的数字与最右端的一个数字调换位置。

将当前魔杖指向的数字+1。(若当前魔杖指向的数字为9则无效)

将当前魔杖指向的数字−1。(若当前魔杖指向的数字为0则无效)

将当前魔杖向右移动一位。

将当前魔杖向左移动一位。

最开始,她的魔杖指向的是最左边的数字。

于是小蟹很好奇,以她的能力,施展几次魔法能完成老师的这道题呢?

Input

多组数据,请处理至文件结束(EOF)

对于每组数据,包含两个6位数,a,b。

Output

对于每组数据,输出一个数,代表最少施展魔法的次数。

Sample input and output

Sample InputSample Output
123456 654321

11

解题报告

不好想。。肯定不能处理操作3和操作4,那样bfs直接爆炸。。。本题连A*也不行。。因为状态数实在太多,又是多Case。。

难保不TLE,因此我们预处理出魔杖能到达地方的状态,之后扫一遍所有状态,加上差值就完辣

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

const int MaxHashSize = 1526597;
const int MaxStatusSize = 5000000;
typedef struct status
{
int step,value;
bool arrive[6];
};

int Head[MaxHashSize];
int Next[MaxStatusSize];
status st[MaxStatusSize];
int caculate[7] = {1000000,100000,10000,1000,100,10,1};
int tar_num[6];

void Hash_init()
{
memset(Head,-1,sizeof(Head));
}

int GetHashNum(int& x)
{
return x % MaxHashSize;
}

bool insert_Hash(int id)
{
int h = GetHashNum(st[id].value);
int t = Head[h];
while(t != -1)
{
if(st[id].value == st[t].value)
return false;
t = Next[t];
}
Next[id] = Head[h];
Head[h] = id;
return true;
}

int bfs()
{
int front = 0,rear = 1;
insert_Hash(0);
while(front < rear)
{
status ss = st[front++];
int num[7];
int ori = ss.value;
for(int i = 6 ; i >=0 ; --i)
{
num[i] = ss.value % 10;
ss.value /= 10;
}
int pos = num[6];
bool flag = true;
if (num[pos] == 0 || pos == 0) flag = false;
if (flag)
{
st[rear] = ss;
int temp = num[0];
num[0] = num[pos];
num[pos] = temp;
int value = 0;
for(int i = 0 ; i < 7 ; ++ i)
value += (num[i]*caculate[i]);
st[rear].value = value;
if (insert_Hash(rear))
{
st[rear].step = ss.step + 1;
st[rear++].arrive[0] = true;
}
num[pos] = num[0];
num[0] = temp;
}
flag = true;
if (num[5]  == 0 && pos == 0) flag = false;
if (pos == 5) flag = false;
if (flag)
{
st[rear] = ss;
int temp  = num[5];
num[5] = num[pos];
num[pos] = temp;
int value = 0;
for(int i = 0 ; i < 7 ; ++ i)
value += (num[i]*caculate[i]);
st[rear].value = value;
if (insert_Hash(rear))
{
st[rear].step = ss.step + 1;
st[rear++].arrive[5] = true;
}
num[pos] = num[5];
num[5] = temp;
}
if (pos < 5)
{
st[rear] = ss;
int value = ori + 1;
st[rear].value = value;
if (insert_Hash(rear))
{
st[rear].step = ss.step + 1;
st[rear++].arrive[pos+1] = true;
}
}
if (pos > 0)
{
st[rear] = ss;
int value = ori - 1;
st[rear].value = value;
if (insert_Hash(rear))
{
st[rear].step = ss.step + 1;
st[rear++].arrive[pos-1] = true;
}
}
}
return rear;
}

int slove(int x)
{
int Mo = 999;
for(int i = 0 ; i < x; ++ i)
{
//cout << "i is " << i << endl;
int num[6];
st[i].value /= 10;
int ori = st[i].value;
for(int j = 5;j >=0 ;--j)
{
num[j] = st[i].value % 10;
st[i].value /= 10;
}
int res = st[i].step;
for(int k = 0 ; k < 6;++k)
if (tar_num[k] != num[k] && !st[i].arrive[k])
{
res = 999;
break;
}
else
res += (abs(tar_num[k]-num[k]));
//cout << "Res is " << res << endl;
Mo = min(Mo,res);
}
return Mo;
}

int main(int argc, char * argv[])
{
int s1,s2;
while(scanf("%d%d",&s1,&s2) == 2)
{
Hash_init();
st[0].value = s1*10;
st[0].step = 0;
memset(st[0].arrive,false,sizeof(st[0].arrive));
st[0].arrive[0] = true;
for(int i = 5;i>=0;--i)
{
tar_num[i] = s2 % 10;
s2 /= 10;
}
cout << slove(bfs()) << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: