其实最终的结果无非是中间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. android studio 9.png 报错

    Eclipse里能正常运行,但是导入到Android Studio里就报如下的错误 百度了下,说有两种解决办法一种是改后缀名,还有一种是重新在Android Studio里画一下点9图片.但是这个项目 ...

  2. Oracle heap 表的主键 dump 分析

    1. 创建heap 表: create table t1 (id char(10) primary key,a1 char(10),a2 char(10),a3 char(10)); SQL> ...

  3. select value from v$diag_info where name='Default Trace File';

    VALUE -------------------------------------------------------------------------------- /u01/diag/rdb ...

  4. Windbg 32位版本和64位版本的选择

    习惯了Vsiual Studio的兄弟们可能会因为先入为主的原因以为所有的调试器都应该像它那样,其实不然,当你安装Debugging Tools for Windows的时候,你将发现有两个系列的工具 ...

  5. JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法

    CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定. 1 byte checksum CRC ...

  6. 指尖上的电商---(3)Solr全文搜索引擎的配置

    接上篇,Solr的准备工作完毕后,本节主要介绍Solr的安装,事实上Solr不须要安装.直接下载就能够了      1.Solr配置 下载地址 :http://lucene.apache.org/so ...

  7. Android 动态生成布局 (多层嵌套)

    Android 除了能够载入xml文件,显示布局外,也能够代码生成布局,并通过setContentView(View view)方法显示布局.单独的一层布局,如一个主布局加一个控件(如Button\i ...

  8. 斯坦福ML公开课笔记15—隐含语义索引、神秘值分解、独立成分分析

    斯坦福ML公开课笔记15 我们在上一篇笔记中讲到了PCA(主成分分析). PCA是一种直接的降维方法.通过求解特征值与特征向量,并选取特征值较大的一些特征向量来达到降维的效果. 本文继续PCA的话题, ...

  9. Terracotta收购Ehcache (转)

    随着Terracotta对Ehcache的收购成行,业界两大知名的开源Java缓存产品走到了一起.以提供JVM级“POJO集群”而闻名于世的Terracotta可以将运行在单个JVM上的多线程应用移植 ...

  10. hdu1695(莫比乌斯反演)

    传送门:GCD 题意:求[1,n],[1,m]gcd为k的对数. 分析:莫比乌斯入反演门题,gcd(x,y)==k等价于gcd(x/k,y/k)==1,求出[1,n][1,m]互质的对数,在减去[1, ...