hdu3278Puzzle
其实最终的结果无非是中间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的更多相关文章
随机推荐
- svn跨机备份
#!/bin/sh svn_bak_dir='/svndata/cloudil' svn_server='svn://172.16.40.200:9999' user=adminread pass=a ...
- callback用法简介
源地址:https://argcv.com/articles/2669.c callback,函数的回调,从ANSI C开始,一直被广为使用.无论是windows API的所谓消息机制,动态链接库的调 ...
- 模仿《百度音乐HD》添加到下载框动画
上次听有人说喜欢<百度音乐HD>添加到下载动画 ,我就尝试模仿了下,没想到,今天code4app(地址)也有了这个,但是 这个动画基本相同,我们的思路还是部一样的. 都可以参考 .主要关键 ...
- Delphi5 update1的序列号
好不容易找到一个: Serial Number: 100-006-1659Key: 6ax0-91x0 ------------------------------------------- 办法2: ...
- 深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)
1,回调函数工作机制 回调函数由操作系统自动调用,回调函数的返回值当然也是返回给操作系统了. 2,截获操作系统发出的消息,截获到后,将另外一个消息返回给操作系统,已达到欺骗操作系统的目的. 下面还是以 ...
- Java发展的时间表
Java发展的时间表. (版本号 名称 中文名 发布日期) JDK 1.1.4 Sparkler 宝石 1997-09-12 JDK 1.1.5 Pumpkin 南瓜 1997-12-13 JDK 1 ...
- c语言太easy笔误的,这将做
调试发现时间写的一样NB代码 test.c int add(string); int main() { char* p = "11222"; add(p); return 0; } ...
- POJ1789 Truck History 【最小生成树Prim】
Truck History Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18981 Accepted: 7321 De ...
- 使用SVN clang: error: linker command failed with exit code 1 (use -v to see invocation)
然后上传到该项目SVN仓库上,例如,下面的错误再次发生再拉到本地编译 ld: library not found for -lxxxxxxxxxxxx clang: error: linker com ...
- hdu1059(多重背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意 : 按顺序读入一些列数,所对应的序列代表价值,数值代表个数(如a[5]=6 ,代表价值为五 ...