其实最终的结果无非是中间8个方块是相同的颜色,外面16个方块是另外两种颜色。那么其实可以把外面两种颜色看作是0,中间的颜色看做是1。

那么题目就变成了把那种颜色看做1,而其它两种颜色看做0,可以用最少的步骤得到结果。

那么24个方块就可以用24位二进制来标记。那么判重的方式找到了,映射为一个int类型的整数hash

而方块的移动可以看做是位运算的组合,慢慢想想就能够用位运算直接在整数hash上运算,而得到另一个整数。

 #include <stdio.h>
#include <string.h>
#include <string>
#include <queue>
#include <iostream>
#include <map>
using namespace std;
int q[<<];
short step[<<];
/*
0 1 2 3 4 5 --> 1 2 3 4 5 0
0 1 2 3 4 5 --> 5 0 1 2 3 4
6 7 8 9 10 11 ->7 8 9 19 11 6 0 6 12 18 --> 6 12 18 0
0 6 12 18 --> 18 0 6 12
1 7 13 19 --> 7 13 19 1
1 7 13 19 --> 19 1 7 13
4
*/
inline int min(const int&a, const int &b)
{
return a < b ? a : b;
}
int tmp[],c;
int inline col1(int k,int s)
{
c = -;
for(int i=; i<; i++)
{
c -= (<<(i*+k));
tmp[i]=s&(<<(i*+k));
}
s=s&c;
tmp[]<<=;
tmp[]>>=;
tmp[]>>=;
tmp[]>>=;
s=s+tmp[]+tmp[]+tmp[]+tmp[];
return s;
}
int inline col2(int k,int s)
{
c = -;
for(int i=; i<; i++)
{
c -= (<<(i*+k));
tmp[i]=s&(<<(i*+k));
}
s=s&c;
tmp[]<<=;
tmp[]<<=;
tmp[]<<=;
tmp[]>>=;
s=s+tmp[]+tmp[]+tmp[]+tmp[];
return s;
}
int inline row1(int k,int s)
{
c = <<(k*);
int tmp = c&s;
s -= tmp;
int t = tmp&(<<(k*));
tmp -= t;
tmp>>=;
tmp +=(t<<);
return s+tmp;
}
int inline row2(int k,int s)
{
c = <<(k*);
int tmp = c&s;
s -= tmp;
int t = tmp&(<<(k*+));
tmp -= t;
tmp<<=;
tmp +=(t>>);
return s+tmp;
}
void bfs()
{
int head = ,tail = ;
int cur = ,tmp,i;
for(i=; i<=; ++i)
cur += <<i;
for(i=; i<=; ++i)
cur+= <<i;
step[cur] = ;
q[tail++] = cur; while(head < tail)
{
cur = q[head++];
for(i=; i<; ++i)
{
tmp = col1(i,cur);
if(!step[tmp])
{ step[tmp] = step[cur] + ;
q[tail++] = tmp;
}
tmp = col2(i,cur);
if(!step[tmp])
{
step[tmp] = step[cur] + ;
q[tail++] = tmp;
}
}
for(i=; i<; ++i)
{
tmp = row1(i,cur);
if(!step[tmp])
{
step[tmp] = step[cur] + ;
q[tail++] = tmp;
}
tmp = row2(i,cur);
if(!step[tmp])
{ step[tmp] = step[cur]+ ;
q[tail++] = tmp;
}
}
}
}
int main()
{
int t,k,i,j,w,g,b;
scanf("%d",&t);
char ch;
bfs();
for(k=; k<=t; ++k)
{
w = g = b = ;
for(i=; i<; ++i)
{
getchar();
for(j=; j<; ++j)
{
scanf("%c",&ch);
if(ch=='B')
b += <<(i*+j);
else if(ch=='G')
g += <<(i*+j);
else
w += <<(i*+j);
}
}
printf("Case %d: %d\n",k,min(step[b]-,min(step[g],step[w])-));
}
}

hdu3278Puzzle的更多相关文章

随机推荐

  1. 4种Delphi IDE的调试时查看内存的方法,太酷了!

    1.ctrl+alt+m,可以查看每个函数过程的内存位置 2.Ctrl+Alt+C 查看代码对应的汇编 3.原来用delphi看变量信息一直是简单的用watch看,但是有时候变量值直接用特定类型看总是 ...

  2. POJ 2112 Optimal Milking【网络流+二分+最短路】

    求使所有牛都可以被挤牛奶的条件下牛走的最长距离. Floyd求出两两节点之间的最短路,然后二分距离. 构图: 将每一个milking machine与源点连接,边权为最大值m,每个cow与汇点连接,边 ...

  3. OpenRisc-30-SD card controller模块分析与验证

    引言 ORPSoC的硬件平台是包含SD card controller控制器的,但是对应的linux里面却没有对应的linux的驱动程序,这使ORPSoC的SD card的使用收到了很大的限制.没有驱 ...

  4. html中加入超链接方式的汇总

    在CSS样式中,对超链接的样式有以下几种定义(1)设置链接未被访问时的样式,具体写法如下:a:link{font-size:10px;... }(2)设置链接在鼠标经过时的样式,具体写法如下:a:ho ...

  5. 居然还有FindFirstChangeNotification函数

    http://download.csdn.net/download/sololie/5966243

  6. Activity组件的生命周期

    一.Activiy组件的三个状态: 1.前台状态(active) : 在屏幕的最上层,页面获得焦点,可以响应用户的操作2.可视状态(paused) : 不能与用户交互,但是还存在于可视区域内,它依然存 ...

  7. 模板的Traits

    Traits含义就是特性,应用Trait模板参数,使得我们的程序既保持灵活性,同时减少类型参数的数量.能够使得我们对函数进行更加细粒度的控制. #ifndef TRAIT_H_ #define TRA ...

  8. [IDEs]Eclipse设置花括号样式

    用惯Vistual Studio,在使用Eclipse时发现有很多东西还是挺不习惯,第一个就要解决花括号的样式 步骤: 1.Windows->Preferences->Java->C ...

  9. leetcode day6 -- String to Integer (atoi) &amp;&amp; Best Time to Buy and Sell Stock I II III

    1.  String to Integer (atoi) Implement atoi to convert a string to an integer. Hint: Carefully con ...

  10. TCP/IP详细解释--TCP/IP可靠的原则 推拉窗 拥塞窗口

    TCP和UDP在同一水平---传输层.但TCP和UDP最不一样的地方.TCP它提供了一个可靠的数据传输服务,TCP是面向连接的,那.使用TCP两台主机通过第一通信"拨打电话"这个过 ...