其实最终的结果无非是中间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. Main Memory Object-Relational Database Management System

    Main Memory Object-Relational Database Management System FastDBMain Memory Relational Database Manag ...

  2. Spring4 MVC 多文件上传(图片并展示)

    开始需要在pom.xml加入几个jar,分别是 <dependency> <groupId>commons-fileupload</groupId> <art ...

  3. QS Network(最小生成树)

    题意:若两个QS之间要想连网,除了它们间网线的费用外,两者都要买适配器, 求使所有的QS都能连网的最小费用. 分析:这个除了边的权值外,顶点也有权值,因此要想求最小价值,必须算边及顶点的权值和. 解决 ...

  4. (76) Clojure: Why would someone learn Clojure? - Quora

    (76) Clojure: Why would someone learn Clojure? - Quora ★ Why would someone learn Clojure?   Edit

  5. Cocos2d-x 创建(create)动画对象CCAnimation报错分析

    本人在使用精灵表单创建动画的过程中突然遇到了一些个问题,下面进行一下分析总结. 根据在Cocos2d-iphone中的经验,我写出了如下的代码: CCSpriteFrameCache::sharedS ...

  6. 无锁队列--基于linuxkfifo实现

    一直想写一个无锁队列,为了提高项目的背景效率. 有机会看到linux核心kfifo.h 原则. 所以这个实现自己仿照,眼下linux我们应该能够提供外部接口. #ifndef _NO_LOCK_QUE ...

  7. servlet其工作原理和例子证明

    servlet简单介绍 当我们在地址栏里面输入www.baidu.com,终于呈如今我们面前的是百度搜索的页面.在这些訪问过程中,都会有一个webserver来处理这些请求以及訪问处理后的结果. 而s ...

  8. C语言内存对齐

    转:http://blog.csdn.net/embeddedman/article/details/7429976 首先由一个程序引入话题:  1 //环境:vc6 + windows sp2 2  ...

  9. 我经历的IT公司面试及离职感受(转)

    毕业后几年一直待在广州,觉得这是一个比较生活化及务实的城市,其互联网公司和相应的投融资环境都不如北深上活跃,大大小小的面试也有几十个,有点规模的公司应该都面试过了,面试一般会见到主力技术人员,技术主管 ...

  10. Android开发 更改返回button的图标

    非常多的Android应用左上角都有返回button 在默认的情况下 ADT会默认给一个返回图标 而作为开发需求 非常多都要求定制一个新的图标 在Android的站点上 发现了2种能够更改的方法 1. ...