HDU 2174 Bridged Marble Rings
题目:Bridged Marble Rings
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2174
题意:如图,要把所有灰色球移动到上圈,每次操作可以转图中虚线圈起的三个圆,求中间圆的最少转数。题目给出的是字符串,g代表灰色球,y代表黄色球,起始位置看标记。

思路:
BFS打表+最小表示法
令g=1,y=0,用int 表示当前状态。
最开始直接用BFS打表,超时超内存,按我最初的算法,所有状态总数为C(26,13)约等于1000多万种。但实际上,因为转动上下两个圈是不增加转数的,所以很多情况是等价的,可以压缩状态数,对于一个状态S,可以转动上圈,下圈使其得到最小表示的状态T。接着存T就可以了。每次,注意,map会超时,后面我改成哈希就过了。。。
具体:每次出队一个状态,将该状态对应的13*13个下一步状态(筛选一下)入队。
AC代码:
#include<stdio.h>
#include<map>
#include<queue>
#include<algorithm>
using namespace std; #define Mod 1000007 //取模的大小,哈希表的大小...
#define Max 100007 //存放的总数
typedef long long LL;
class Hash //手写哈希
{
public:
int hs[Mod]; //哈希值 设定的哈希函数为 原值 % Mod ,所以哈希值有可能是 0 ~ Mod-1
int next[Max]; //链表 存放哈希值相等的一条链,他的大小取决于所有原值的数量
LL S[Max]; //存放原值
int H[Max]; //存放所有哈希值
int sn; //不同原值的数量
int hn; //不同哈希值的数量
Hash() //构造函数: 定义Hash类变量时初始化
{
sn=;
hn=;
for(int i=;i<Mod;i++)
hs[i]=;
}
void clear() //清空函数
{
sn=;
for(int i=;i<hn;i++)
hs[H[i]]=;
hn=;
}
void add(LL s) //加入
{
int ha=abs(s)%Mod; //计算哈希值
if(hs[ha]==) //如果该哈希值还未出现过
{
H[hn++]=ha; //将该哈希值记录起来,同时哈希值数量加 1
}
sn++; //0 表示结尾,所以从1 开始存,原值数量加 1,特别针对 hs数组
S[sn]=s; //将原值记录起来
next[sn]=hs[ha]; //原本原值记录位置
hs[ha]=sn; //最新原值记录位置,如果从0 开始存,就无法判断此时是空还是1个值
//比如:5 和 10 有一样的哈希值 ,并且 5 和 10 先后加入 那么有:
//5 加入: next[1] = 0; hs[5] = 1; hs[5] 是哈希值为5 的头,表示第一个原值在1的位置
//10加入: next[2] = 1; hs[5] = 2; 表示第一个哈希值为5的在2,第二个在1,第三个不存在
}
int find(LL s) //查找
{
int ha=abs(s)%Mod; //计算哈希值
int k=hs[ha]; //头
while(k!=)
{
if(S[k]==s) return k;//找到
k=next[k]; //下一个节点
}
return ; //表示没找到
}
}; int move(int s, int i){
int gao = (s>>)&0x1FFF;
int di = s&0x1FFF;
if(i==){
int tmp = di&;
di = di >> ;
di = di | (tmp << );
}
else if(i==){
int tmp = gao&;
gao = gao >> ;
gao = gao | (tmp << );
}
else{
int a = (gao & 0x1C00)>>;
int b = (di & 0x1C00)>>;
gao = gao & 0x3FF;
di = di & 0x3FF;
gao = (b<<)| gao;
di = (a<<) | di;
}
return (gao<<)|di;
} map<int, int> mp;
int c[<<]; int min_code(int s){
int gao = (s>>)&0x1FFF;
int di = s&0x1FFF;
gao = c[gao];
di = c[di];
return (gao<<)|di;
}
int min_code_1(int s){
int ms=s;
for(int i=; i<; i++){
int tmp = s&;
s >>= ;
s = s | (tmp << );
if(ms>s) ms=s;
}
return ms;
} Hash hs;
queue<int> q; void mov(int ms){
int a=ms;
for(int i=; i<; i++){
a=move(a, );
int b=a;
for(int j=; j<; j++){
b=move(b, );
int c=move(b, );
int mc=min_code(c);
int cx=hs.find(mc);
if(cx==){
hs.add(mc);
mp[mc]=mp[ms]+;
q.push(mc);
}
}
}
} void bfs(int s){
s=min_code(s);
mp[s]=;
q.push(s);
while(q.size()){
int a=q.front();
q.pop();
mov(a);
}
} int main(){
for(int i=; i<(<<); i++){
c[i]=min_code_1(i);
}
int t=0x3FFE000;
bfs(t);
char tmp[];
while(~scanf("%s", tmp)){
int s=;
for(int i=; tmp[i]; i++){
if(tmp[i]=='g') s=s*+;
else s=s*;
} if(s==t) printf("0\n");
else printf("%d\n", mp[min_code(s)]-);
}
return ;
}
HDU 2174 Bridged Marble Rings的更多相关文章
- 搜索专题题解(FJUT - OJ 17级搜索强化训练)
题目连接:http://120.78.128.11/Contest.jsp?cid=221#H 题目都比较难,每道题都很经典,我也做的很慢,这篇博文算是个收录.具体题目题解点击下面超链接吧. 一.Br ...
- Chinese Rings hdu 2842 矩阵快速幂
Chinese Rings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 2842 Chinese Rings(常数矩阵)
Chinese Rings 转载自:点这里 [题目链接]Chinese Rings [题目类型]常数矩阵 &题意: 一种中国环,解开第k个环需要先解开全部的前(k-2)个环,并留有第(k-1) ...
- HDU 2842 Chinese Rings(矩阵高速功率+递归)
职务地址:HDU 2842 这个游戏是一个九连环的游戏. 如果当前要卸下前n个环.由于要满足前n-2个都卸下,所以要先把前n-2个卸下.须要f(n-2)次.然后把第n个卸下须要1次,然后这时候要卸下第 ...
- hdu 2842 Chinese Rings
点击打开hdu2842 思路: 矩阵快速幂 分析: 1 题目的意思是给定n个环,和一些规则要把所有的环全部拆下最少需要的步数 2 题目规定如果要拆第n个环,那么第n-1个要挂着,n-2环要被拆下.那么 ...
- HDU 2842 Chinese Rings( 递推关系式 + 矩阵快速幂 )
链接:传送门 题意:解 N 连环最少步数 % 200907 思路:对于 N 连环来说,解 N 连环首先得先解 N-2 连环然后接着解第 N 个环,然后再将前面 N-2 个环放到棍子上,然后 N 连环问 ...
- hdu 2842 Chinese Rings 矩阵快速幂
分析: 后面的环能不能取下来与前面的环有关,前面的环不被后面的环所影响.所以先取最后面的环 设状态F(n)表示n个环全部取下来的最少步数 先取第n个环,就得使1~n-2个环属于被取下来的状态,第n-1 ...
- HDU——PKU题目分类
HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...
- HDU 1007 Quoit Design(二分+浮点数精度控制)
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
随机推荐
- Nginx安装与代理
1.第一步 - 添加Nginx存储库 要添加CentOS 7 EPEL存储库,请打开终端并使用以下命令: sudo yum install epel-release 2.第二步 - 安装Nginx 现 ...
- java~springboot~gradle里的docker集成
在springboot里,我们的task任务可以添加docker构建的功能,在gradle集成环境里,直接可以实现编译,测试,打包镜像的流水线作业,很是方便! 下面分享给大家,在gradle里添加do ...
- Linux最小系统移植之早期打印CONFIG_EARLY_PRINTK
请先参考先前博文: Linux最小系统移植之早期打印CONFIG_DEBUG_LL , 因为eraly_printk其实就是对printch()封装的 一. 必要选项(在上面链接选中的前提下再新增 ...
- SLAM+语音机器人DIY系列:(三)感知与大脑——4.音响麦克风与摄像头
摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...
- 搞懂Redis RDB和AOF持久化及工作原理
前言 因为Redis的数据都储存在内存中,当进程退出时,所有数据都将丢失.为了保证数据安全,Redis支持RDB和AOF两种持久化机制有效避免数据丢失问题.RDB可以看作在某一时刻Redis的快照(s ...
- 极光推送经验之谈-Java后台服务器实现极光推送的两种实现方式
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6439313.html Java后台实现极光推送有两种方式,一种是使用极光推送官方提供的推送请 ...
- 【憩园】C#并发编程之异步编程(三)
写在前面 本篇是异步编程系列的第三篇,本来计划第三篇的内容是介绍异步编程中常用的几个方法,但是前两篇写出来后,身边的朋友总是会有其他问题,所以决定再续写一篇,作为异步编程(一)和异步编程(二)的补 ...
- chrome主页被篡改为hao123 win10系统
应该是开了个从流氓网站下的蓝灯,然后发现主页被篡改 尝试chrome设置修改无效,应该是快捷方式被改了 系统 win10 1.打开对应的下面两个地址,找到chrome的快捷方式,右键属性 C:\Use ...
- 005. [转] SSH端口转发
玩转SSH端口转发 SSH有三种端口转发模式,本地端口转发(Local Port Forwarding),远程端口转发(Remote Port Forwarding)以及动态端口转发(Dynamic ...
- vue中使用百度地图,悬浮窗搜索功能
https://www.cnblogs.com/shuaifing/p/8185311.html 侵删 <template> <div id="all"> ...