题目链接 : http://acm.xidian.edu.cn/land/problem/detail?problem_id=1006

Description

  wm最近喜欢上一种无聊的转盘解锁游戏,他每天都会为这游戏消磨上三个小时的时间。这游戏由三个正六边形拼成,拼成后一共有13个点,其中有4个黑点和9个白点,如下图。每一步可以顺时针或逆时针转动三个六边形的任意一个60度,转动时六边形的顶点也会相应转动,而这游戏的目的是把四个黑点都转到中间(图中最后一个状态)。这是一个很简单的游戏,想达到游戏目的并不难,但wm觉得这样没挑战性,他决定对于任意一个初始状态,用最少的步数去玩这个游戏。

Input
  输入包含多组数据(500组),EOF结束。
每组数据都只有一行13个字符的01串,以从上到下,从左到右的点的顺序表示初始状态(这个由三个正六边形拼成图形最上面一排两个点编号为1 2,第二排三个点编号为3 4 5,依此类推,最后一个点编号为13。第一组样例为上图的初始状态),其中1表示黑点0表示白点。
Output
  每组数据输出一行,解出游戏需要的最小步数。
Sample Input
0000000101011
1011000001000
Sample Output
3
2
 
 
题解:
每个六边形,可以朝两个方向旋转,共有3个六边形,共每个状态可以变化到其他六个状态。
假设初始状态是S,剩下变换后的六个状态分别是S1, S2, S3, S4, S5, S6 。
一个状态最快旋转得到期望结果的最小次数假定是 Res[S], 那么有以下结论:
Res[S] = min{Res[S1], Res[S2],Res[S3],Res[S4], Res[S5],Res[S6]}  +  1  ;
那么这个问题变得简单了,其实就是一个递归可以解决的问题。但是这不是ACM的精神,因为这个方法不是最优的,想想哪里可以优化,
递归的方法会出现大量的重复计算,因为S状态执行3次S1 和 执行3次S2后会得到相同的状态,为了避免这种重复的计算我们采用动态规划算法。
初始状态是期望的结果S=0x348 (二进制为  0001101001000),0标示白色,1标示黑色,上图中1序号位置对应的2进制数字的最低位,依次类推。
初始的Res[0x348] = 0 ;
初始状态S[0] = 0x348 ;
然后分别计算,从S[0] 经过1次变换可得到的6种状态,这六种状态的Res为1,然后依次计算, 状态的最大数是0x1E00 (二进制为1111000000000)
 
附上代码实现:
 #include "stdio.h"

 // change status
int turn(int status,int op)
{
static int ops[][]={
{, , , , , }, {, , , , , },
{, , , , , }, {, , , , , },
{, , , , , }, {, , , , , }}; //// trans status to node status
int node[]={} ;
int tmp , i ;
for(i = ; status ; status>>=) {
node[i++] = status & ;
}
//// do operation , and get res for(tmp = node[ops[op][i=]]; i < ; i++){
node[ops[op][i]] = node[ops[op][i+]] ;
}
node[ops[op][]] = tmp ;
for(i = ; i < ; i++){
status |= node[i]<<i ;
}
return status ;
} int main()
{
///// the max number status is 1111000000000 , is 0x1E00
int status[int(0x1E01)] = {} ;
int res[int(0x1E01)] = {} ;
///// final status is 0001101001000 , is 0x348
res[int(0x348)] = ;
status[] = 0x348 ;
int s_sum = ;
int i , j ;
char str[] = {};
///// Cal the res array
for(i = ; i < s_sum ; i++){
for(j = ; j < ; j++){
int next_s = turn(status[i],j);
if(res[next_s]<=){
res[next_s] = res[status[i]] + ;
status[s_sum++] = next_s ;
}
}
}
///output answer
for(;scanf("%s",str)!=EOF;printf("%d\n",res[j])){
for(i = , j = ; i < ; i++){
j |= (str[i]-'')<<i ;
}
}
return ;
}

题解西电OJ (Problem 1006 - 转盘游戏)--动态规划的更多相关文章

  1. 题解西电OJ (Problem 1007 -做一名正气的西电人 )--长整型计算

    Description 一天,wm和zyf想比比谁比较正气,但正气这种东西无法量化难以比较,为此,他们想出了一个方法,两人各写一个数字,然后转化为二进制,谁的数字中二进制1多谁就比较正气! Input ...

  2. 题解西电OJ (Problem 1005 -跳舞毯)--动态规划

    Description zyf不小心得了一种怪病,为了维持一天的精力他必须不停跳动.于是他买了一条跳舞毯,每天跳上几小时.众所周知,跳舞毯是给定一个序列,让你在指定时间踏指定的按钮,但zyf似乎不怎么 ...

  3. 题解西电OJ (Problem 1004 -亚特兰提斯)--最小生成树

    Description 为了找寻沉睡的亚特兰提斯大陆,wm来到了大西洋上进行探险,找了半个月仍一无所获.然而在一次突袭而来的暴风雨后,wm的船莫名地驶入了一片未知的区域,发现了一个地图上未标记的岛屿, ...

  4. 题解西电OJ (Problem 1003 -最喜欢的数字)--动态规划

    Description zyf最喜欢的数字是1!所以他经常会使用一些手段,把一些非1的数字变 成1,并为此得意不已.他会且仅会的两种手段是: 1.把某个数m除以某个质数p——当然p必须能整除这个数,即 ...

  5. 题解西电OJ (Problem 1008 - 数星星)

    题目内容: Description “不要问我太阳有多高 我会告诉你我有多真 不要问我星星有几颗 我会告诉你很多很多” 一天Qinz和wudired在天上数星星,由于星星可以排列成一条直线,他们比赛看 ...

  6. 转盘游戏[XDU1006]

    Problem 1006 - 转盘游戏 Time Limit: 1000MS   Memory Limit: 65536KB   Difficulty: Total Submit: 87  Accep ...

  7. 『ACM C++』HDU杭电OJ | 1415 - Jugs (灌水定理引申)

    今天总算开学了,当了班长就是麻烦,明明自己没买书却要带着一波人去领书,那能怎么办呢,只能说我善人心肠哈哈哈,不过我脑子里突然浮起一个念头,大二还要不要继续当这个班委呢,既然已经体验过就可以适当放下了吧 ...

  8. C#利用POST实现杭电oj的AC自动机器人,AC率高达50%~~

    暑假集训虽然很快乐,偶尔也会比较枯燥,,这个时候就需要自娱自乐... 然后看hdu的排行榜发现,除了一些是虚拟测评机的账号以外,有几个都是AC自动机器人 然后发现有一位作者是用网页填表然后按钮模拟,, ...

  9. Problem 1014 xxx游戏 暴力+拓扑排序

    题目链接: 题目 Problem 1014 xxx游戏 Time Limit: 1000 mSec Memory Limit : 32768 KB 问题描述 小M最近很喜欢玩XXX游戏.这个游戏很简单 ...

随机推荐

  1. MVC 自定义AuthorizeAttribute 实现权限验证

    MVC内置的AuthorizeFilter先于Action/Result过滤器执行,为网站权限验证提供了很好的一套验证机制. 通过自定义的AuthorizeAttribute可以实现对用户权限的验证. ...

  2. The 5th Zhejiang Provincial Collegiate Programming Contest---ProblemG:Give Me the Number

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2971 题意:将输入的英文数字表达转化为阿拉伯数字. #include< ...

  3. 推荐牛X的一本JS书

    主要是看阮一峰的教程时,他参考书目里有这一本中文的, 找来一看,果然高.. 练习一下. function Base(name) { this.name = name; this.getName = f ...

  4. linux mysql为root用户初始化密码和改变root密码

    初始化密码: 由于安装MySQL完后,MySQL会自动提供一个不带密码的root用户,为了安全起见给root设置密码: #mysqladmin -u root password 123 (123为密码 ...

  5. c++ 基础学习: 左值 概念cocos2d-x3.0的实际应用

    左值:概念baidu 1.2.6.2 与Cocos2d-x内存管理的结合 在2.x的使用场景中,CCArray和CCDictionary通常被分配在堆上,我们不得不需要考虑在适当的地方释放其内存.新的 ...

  6. PJSIP在windows(xp或者win7)下的编译,编译工具是vs2008,PJSIP版本2.3

    PJSIP是一个开源的SIP协议库,它实现了SIP.SDP.RTP.STUN.TURN和ICE.PJSIP作为基于SIP的一个多媒体通信框架提供了非常清晰的API,以及NAT穿越的功能.PJSIP具有 ...

  7. WPF之小动画一

    定义动画: 直接使用Element进行BeginAnimation DoubleAnimation animation = new DoubleAnimation(); animation.By = ...

  8. 一步一步制作yaffs/yaffs2根文件系统(四)---构建etc、dev等剩余目录

    开发环境:Ubuntu 12.04 开发板:mini2440  256M NandFlash   64M SDRAM 交叉编译器:arm-linux-gcc 4.4.3点此可下载 BusyBox版本: ...

  9. C#中的Marshal

    Const.MaxLengthOfBufferd的长度固定为0x2000   也就是8192 private bool SendMessage(int messageType, string ip, ...

  10. js正则表达式中的特殊字符

    正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...