HDU 2209(数据弱,双向直接过)
....由于某些人认为双向过这道比较爽,于是草草coding一番,用了G++才勉强过掉.
DK大牛说了,双向不能求出最优解,因为它不能保证起点出发10步终点出发1步的最优,和起点出发6步和终点出发6步的次优中,前者首先被发现....
正规解法是枚举第一格翻和不翻的状态,然后后面的跟着要求翻........
但双向广搜的方法值得借鉴 因此保存下我的代码思路.
要点是:
1.二进制位状态保存
2.长度记录
3.判重hash
4.类型区分
5.位运算加速
#include <iostream>
#include <queue>
using namespace std;
char key[25];
long hash_st[(1<<20)+10];
long hash_ed[(1<<20)+10];
long st;
long ed;
long len;
const long ST=1;
const long ED=2;
typedef struct
{
long type;
long state;
long len;
}node;
queue<node> q;
inline void Bfs()
{
while (!q.empty())
{
q.pop();
}
node Start,End;
Start.state=st;
End.state=ed;
Start.type=ST;
End.type=ED;
Start.len=0;
End.len=0;
q.push(Start);
q.push(End);
bool finish=false;
long cost=0;
while (!q.empty())
{
node t=q.front();
q.pop();
if (t.type==ST)
{
if (hash_ed[t.state])
{
cost=t.len+hash_ed[t.state];
finish=true;
break;
}
}
else
{
if (hash_st[t.state])
{
cost=t.len+hash_st[t.state];
finish=true;
break;
}
}
long j;
long temp;
for (j=0;j<len;++j)
{
temp=t.state;
if (j==0)
{
temp=temp^(1<<(len-1));
if (j+1<len)
{
temp=temp^(1<<(len-2));
}
}
else if(j+1==len)
{
temp=temp^1;
if (j-1>=0)
{
temp=temp^2;
}
}
else
{
temp=temp^(1<<(len-j-1));
temp=temp^(1<<(len-j));
temp=temp^(1<<(len-j-2));
}
node tt;
if (t.type==ST)
{
if (!hash_st[temp])
{
hash_st[temp]=t.len+1;
tt.len=hash_st[temp];
tt.state=temp;
tt.type=ST;
q.push(tt);
}
}
else
{
if (!hash_ed[temp])
{
hash_ed[temp]=t.len+1;
tt.len=hash_ed[temp];
tt.state=temp;
tt.type=ED;
q.push(tt);
}
}
}
}
if (finish)
{
printf("%ld\n",cost);
}
else
{
printf("NO\n");
}
}
int main()
{
while (gets(key))
{
long i;
st=ed=0;
for (i=0;key[i]!='\0';++i)
{
st=(st<<1)+(key[i]-'0');
}
if (st==0)
{
printf("0\n");
continue;
}
len=i;
memset(hash_st,0,1<<(len+2));
memset(hash_ed,0,1<<(len+2));
Bfs();
}
return 0;
}
#include <queue>
using namespace std;
char key[25];
long hash_st[(1<<20)+10];
long hash_ed[(1<<20)+10];
long st;
long ed;
long len;
const long ST=1;
const long ED=2;
typedef struct
{
long type;
long state;
long len;
}node;
queue<node> q;
inline void Bfs()
{
while (!q.empty())
{
q.pop();
}
node Start,End;
Start.state=st;
End.state=ed;
Start.type=ST;
End.type=ED;
Start.len=0;
End.len=0;
q.push(Start);
q.push(End);
bool finish=false;
long cost=0;
while (!q.empty())
{
node t=q.front();
q.pop();
if (t.type==ST)
{
if (hash_ed[t.state])
{
cost=t.len+hash_ed[t.state];
finish=true;
break;
}
}
else
{
if (hash_st[t.state])
{
cost=t.len+hash_st[t.state];
finish=true;
break;
}
}
long j;
long temp;
for (j=0;j<len;++j)
{
temp=t.state;
if (j==0)
{
temp=temp^(1<<(len-1));
if (j+1<len)
{
temp=temp^(1<<(len-2));
}
}
else if(j+1==len)
{
temp=temp^1;
if (j-1>=0)
{
temp=temp^2;
}
}
else
{
temp=temp^(1<<(len-j-1));
temp=temp^(1<<(len-j));
temp=temp^(1<<(len-j-2));
}
node tt;
if (t.type==ST)
{
if (!hash_st[temp])
{
hash_st[temp]=t.len+1;
tt.len=hash_st[temp];
tt.state=temp;
tt.type=ST;
q.push(tt);
}
}
else
{
if (!hash_ed[temp])
{
hash_ed[temp]=t.len+1;
tt.len=hash_ed[temp];
tt.state=temp;
tt.type=ED;
q.push(tt);
}
}
}
}
if (finish)
{
printf("%ld\n",cost);
}
else
{
printf("NO\n");
}
}
int main()
{
while (gets(key))
{
long i;
st=ed=0;
for (i=0;key[i]!='\0';++i)
{
st=(st<<1)+(key[i]-'0');
}
if (st==0)
{
printf("0\n");
continue;
}
len=i;
memset(hash_st,0,1<<(len+2));
memset(hash_ed,0,1<<(len+2));
Bfs();
}
return 0;
}