若果有一组硬币,(假定有十个),每一个硬币仅仅有两个面,正面用以表示。反面用零表示.

给定目标(初始状态)1111100000 正正正正正反反反反反

(目标状态)   1000011101 正反反反反正正正反正

规定每次仅仅能够翻转相邻的两个硬币(他们各自成为原来的对立面)

问题,至少用多少次就能够达到目的.

将每一种状态标记为,每一次的硬币翻动(1-9)状态i。都会使。当前状态变为还有一种状态状态i+1,假设在状态

i+1的位置,翻动和对应的位置,则会,回到状态i,因此推断是(状态与状态之间的转换)能够互相进行.以此推断图的搜索.

此处採索,

方法一

分析.

每一个硬币翻转后都会(且必须)影响一硬币,硬币个数大于一

考虑每次翻转都会有两个硬币翻转到相反状态,假设目标与初始有基数个不同样。就不能达到目标状态.

我们尽可能的是硬币当前硬币接近给定状态

因此从左向右,假设i号硬币与目标同样,跳过。否则翻转i,i+1号硬币.(i<n),翻转次数加一.

当到i==n是假设i号与目标同样则得到翻转次数.

否则不能通过有该翻转规则得到,由于有一个不同(1。是基数而该规则是,每次改变两个硬币).

问题是怎样证明最有性.

一个硬币假设被翻转偶数次相当与没有翻转

若被翻转多次,如果硬币i被翻转n次,相当于n%2次

那麽i-1,被翻转x次(相当于x%2),i+1被翻转了n-x次((n-x)%2)

x为偶数。n-x为奇数 n为奇数 翻转i和i+1

x为偶数 n-x为偶数 n也为偶数 相当于没有不论什么硬币被翻转

x为奇数 n-x为偶数 n为基数      相当于值翻转i-1,i

x为基数n-x为基数翻转了i-1,i+1.

通过上述四种情况我们发现能够对一个硬币有两种操作

1.翻转左右各一次(多次效果同样次数增多不是问题的解)使得相距一个的硬币翻转

2.翻转左边一次或者右边一次,效果都是使得相邻的硬币发生翻转

以以下情况举例说明2覆盖1

a.假如 要是0 0 0 翻转到 1 0 1

第一种翻转方法翻转两边使得达到结果次数为2

另外一种方法翻转1,2,使得达到效果结果次数为2

b.要是0 0 0 变为 1 1 0

第一种方式不能达到,而另外一种方式仅仅要翻转1。影响2(翻转2,影响1)就可以结果为1

由情况a,b能够看出要改变一个硬币仅仅需改变他和他相邻的硬币就可以.

相邻的有两边。那麽要改变硬币i,究竟要硬向那边,能够从第一个開始来推断是否i号须要被改变,那麽左边的都是完毕改变的,因此仅仅需顾虑右边就好了.

那可能会有疑问了,会不会从右边開始结果更少呢?

从两边開始结果一样的

非常明确的知道。全部翻转的点是与目标不同的点.如今有m个(m是偶数)由于已经证明结论基数个不同样硬币是不可能相邻翻转来改变是指同样。此时设有0<=i<j<=n;

a[i],a[j]都与目标不同样,此时从左向右还是从右翻转都是j-i次,那麽原硬币中有m个与终于结果不同样,此时可将这m开做k(o..m/2)的ik..jk.不同样的亮亮对,他们翻转操作次数

都是k(1...m/2) 求和ij-ik,因此偶数(可通过翻转到达的情况是从左到右从右到左是同样的).

比如记i号硬币起始情况与终于情况同样为1,否则为零那麽对以下的情况用上面的结论来计算结果.

1 0 1 0 0 0 1 0 1 0

从左向右(4-2)+ (6-5)+ (10 -8)= 5次

从右向左 (10-8) + (6-5) + (4-2) =5次

上面规律应征名,全部这杨m为偶数结果,从左向右,从右向左都同样。

以下解法即从左向右.

#include <stdio.h>
int main(){
int count=0,i;
int a[10];
int b[10];
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(i=0;i<10;i++){
scanf("%d",&b[i]);
}
for(i=0;i<9;i++){
if(a[i]!=b[i]){
a[i]=!a[i];
a[i+1]=!a[i+1];
count++;
}
}
printf("%d\n",a[i]==b[i]? count:-1);
return 0;
}

方法二

採取bfs,搜素状态树就可以.

要点两个:

1.状态的保存(判反复节点).若果节点反复则不应打开(去遍历他所相应的节点间)。

2.状态的表示,该题目的状态的表示,使用简单的哈希相应关系.

#include <iostream>
#include <cstring>
using namespace std;
const int size = 1000000+100;
typedef int state[10];
state st[size];
int vis[size]={0};
int dis[size]={0};
int getkey(state &s)
{
int i,adder=0;
for(i=0;i<10;i++){
adder=adder*2+s[i];
}
return adder;
}
int isvis(state &s){
int key=getkey(s);
if(vis[key])
return 1;
else {
vis[key]=1;
return 0;
}
}
int bfs(int front,int rear,state goal)
{
int i,j,k;
while(front!=rear){
state &s=st[front];
if(memcmp(goal,s,sizeof(s))==0)
return dis[front];
else{
for(i=0;i<9;i++){
state &t=st[rear]; memcpy(&t,&s,sizeof(s));
t[i]=!t[i];
t[i+1]=!t[i+1];
dis[rear]=dis[front]+1;
if(!isvis(t))
rear++;
}
}
front++;
}
return -1;
}
int main()
{
int front=1,rear=2,i,j,k;
state goal;
int distance=-1;
for(i=0;i<10;i++){
cin>>st[front][i];
}
for(i=0;i<10;i++){
cin>>goal[i];
}
distance=bfs(front,rear,goal);
cout<<distance<<endl;
return 0;
}

给出10个硬币初始状态,和终于状态得到最短反转步数.

log翻硬币的更多相关文章

  1. bzoj 3517: 翻硬币

    3517: 翻硬币 Time Limit: 1 Sec  Memory Limit: 128 MB Description 有一个n行n列的棋盘,每个格子上都有一个硬币,且n为偶数.每个硬币要么是正面 ...

  2. 51nod 1613翻硬币

    题目链接:51nod 1613 翻硬币 知乎上的理论解法http://www.zhihu.com/question/26570175/answer/33312310 本题精髓在于奇偶性讨论. 若 n ...

  3. HDU 3537 (博弈 翻硬币) Daizhenyang's Coin

    可以参考Thomas S. Ferguson的<Game Theory>,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈. 这种博弈属于Mock Turtles,它的 ...

  4. hdu 3537(博弈,翻硬币)

    题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的. 分析: 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初 ...

  5. 翻硬币|2013年蓝桥杯B组题解析第八题-fishers

    翻硬币 小明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:oooooo 如果同时翻转左 ...

  6. PREV-6_蓝桥杯_翻硬币

    问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如果同时翻转左边的两个 ...

  7. HDU 3537 基础翻硬币模型 Mock Turtles 向NIM转化

    翻硬币游戏,任意选3个,最右边的一个必须是正面.不能操作者败. 基本模型..不太可能自己推 还是老实记下来吧..对于单个硬币的SG值为2x或2x+1,当该硬币的位置x,其二进制1的个数为偶数时,sg= ...

  8. hdu 3537 翻硬币 每次能翻1个 或2个 或3个

    N 枚硬币排成一排,有的正面朝上,有的反面朝上.我们从左开始对硬币按1 到N 编号. 第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面. 第二,谁不能翻谁输. ...

  9. 算法笔记_194:历届试题 翻硬币(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情 ...

随机推荐

  1. 解决虚拟内存不够导致Eclipse is not responding

    安装目录下eclipse.ini中: 修改参数至必要大小. e.g. -vmargs-Djava.net.preferIPv4Stack=true-Dosgi.requiredJavaVersion= ...

  2. Intellij IDEA 常用 设置 及 快捷键 (持续更新)

    Transparent native-to-ascii conversion以下设置都可以通过 设置中的搜索框 进行关键字搜索 0, 打开Project 设置 Command + ; 1, 打开Mod ...

  3. iOS开发之SDWebImage详解

    介绍 github地址: https://github.com/rs/SDWebImage 简介 一个异步图片下载及缓存的库 特性: 一个扩展UIImageView分类的库,支持加载网络图片并缓存图片 ...

  4. File中操作路径的API(转)

    这几天一直在搞Java,模板引擎系列和程序猿执业修养系列都暂停了,在Java上忙的不亦乐乎!由于对Java还不太熟悉,经历了各种纠结终于完成了任务.以下是关于Java获取当前目录的方法的备忘录. 原文 ...

  5. mongodb 限制ip访问

    <pre name="code" class="python">一.限制访问IP和端口 MongoDB可以限制只允许某一特定IP来访问,只要在启动时 ...

  6. 宣布 Windows Azure 通过 PCI DSS 合规性验证并且 ISO 认证范围扩大,同时正式发布 Windows Azure Hyper-V 恢复管理器和其他更新功能

    今天,我们高兴地宣布两个重大里程碑事件,客户将能借此提高基于 Windows Azure 构建安全且合规的应用程序的能力.此外,我们还宣布正式发布 Windows Azure Hyper-V 恢复管理 ...

  7. Tomcat7 + JRebel6.3.0 + IntelliJ idea 热部署配置过程+错误分析

    以前使用Tomcat的时候直接就可以热部署,现在换了一个使用Spring框架的项目突然就不能热部署了. 网上说在tomcat里conf/context.xml中加入 <Context antiJ ...

  8. Buy Tickets(线段树)

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 16607   Accepted: 8275 Desc ...

  9. Strategic Game(匈牙利算法,最小点覆盖数)

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  10. Codeforces Round #198 (Div. 2) B. Maximal Area Quadrilateral

    B. Maximal Area Quadrilateral time limit per test 1 second memory limit per test 256 megabytes input ...