其实最终的结果无非是中间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. mxGraph改变图形大小重置overlay位置

    要在改变图形大小的时候改变overlay的位置.那肯定就要对重置图形大小的方法进行改造了.以下是源文件里的代码 mxGraph.prototype.resizeCells = function(cel ...

  2. UNIX下改动时间简单一例

    UNIX下改动时间简单一例 仅仅输入date就显示当前的工作站时间,假设有root超级用户权限,加上參数能够改动 工作站的时间. 格式:date mmddHHMM[cc]yy mm--月份,dd--日 ...

  3. JAVA的extends使用方法

    理解继承是理解面向对象程序设计的关键.在Java中,通过keywordextends继承一个已有的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类).在Java中不同意多继承. (1)继承 ...

  4. JavaScript面向对象编程(10)高速构建继承关系之对象拷贝

    前面的样例我们是通过构造器创建对象.而且希望该对象继承来自另外一个构造器的对象 我们也能够直接面向一个对象来达成继承的目的.使用下属步骤: 1.拷贝一个对象 2.给新对象加入属性 /** * 通过拷贝 ...

  5. 怎样获取自己的SSL证书

    2.创建证书,注意这里的common name应该填你的server name $ openssl req -new -key key.pem -out request.pem Country Nam ...

  6. Codeforce 143B - Help Kingdom of Far Far Away 2

    B. Help Kingdom of Far Far Away 2 time limit per test 2 seconds memory limit per test 256 megabytes ...

  7. Codeforces Round #252 (Div. 2) B. Valera and Fruits(模拟)

    B. Valera and Fruits time limit per test 1 second memory limit per test 256 megabytes input standard ...

  8. Spark简述及基本架构

    Spark简述 Spark发源于美国加州大学伯克利分校AMPLab的集群计算平台.它立足 于内存计算.从多迭代批量处理出发,兼收并蓄数据仓库.流处理和图计算等多种计算范式. 特点: 1.轻 Spark ...

  9. nagios二次开发(五岁以下儿童)---nagios和nagiosql关系

    基于nagios和nagiosql理解.这将是这两个梳理比较粗糙的简单关系,有关详细信息,请参阅下面的图如:      从上面的关系图中能够看出,nagios与nagiosql共享了主机.主机组.服务 ...

  10. hdu1428之dfs+spfa

    漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...