log翻硬币
若果有一组硬币,(假定有十个),每一个硬币仅仅有两个面,正面用以表示。反面用零表示.
给定目标(初始状态)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翻硬币的更多相关文章
- bzoj 3517: 翻硬币
3517: 翻硬币 Time Limit: 1 Sec Memory Limit: 128 MB Description 有一个n行n列的棋盘,每个格子上都有一个硬币,且n为偶数.每个硬币要么是正面 ...
- 51nod 1613翻硬币
题目链接:51nod 1613 翻硬币 知乎上的理论解法http://www.zhihu.com/question/26570175/answer/33312310 本题精髓在于奇偶性讨论. 若 n ...
- HDU 3537 (博弈 翻硬币) Daizhenyang's Coin
可以参考Thomas S. Ferguson的<Game Theory>,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈. 这种博弈属于Mock Turtles,它的 ...
- hdu 3537(博弈,翻硬币)
题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的. 分析: 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初 ...
- 翻硬币|2013年蓝桥杯B组题解析第八题-fishers
翻硬币 小明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:oooooo 如果同时翻转左 ...
- PREV-6_蓝桥杯_翻硬币
问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如果同时翻转左边的两个 ...
- HDU 3537 基础翻硬币模型 Mock Turtles 向NIM转化
翻硬币游戏,任意选3个,最右边的一个必须是正面.不能操作者败. 基本模型..不太可能自己推 还是老实记下来吧..对于单个硬币的SG值为2x或2x+1,当该硬币的位置x,其二进制1的个数为偶数时,sg= ...
- hdu 3537 翻硬币 每次能翻1个 或2个 或3个
N 枚硬币排成一排,有的正面朝上,有的反面朝上.我们从左开始对硬币按1 到N 编号. 第一,游戏者根据某些约束翻硬币,但他所翻动的硬币中,最右边那个硬币的必须是从正面翻到反面. 第二,谁不能翻谁输. ...
- 算法笔记_194:历届试题 翻硬币(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情 ...
随机推荐
- linux安装LNMP的资源
wget http://nginx.org/download/nginx-0.7.69.tar.gz wget http://museum.php.net/php5/php-5.2.10.tar.gz ...
- javascript 检测密码强度 美化版
模仿美团的美化 <!DOCTYPE> <head runat="server"> <title></title> <link ...
- 51cto培训课程
课程: 云计算: OpenStack | 虚拟化 | 云平台 | Office 365 | 云服务 | Docker | 其他 大数据: Spark | Hadoop | Storm | Hive | ...
- 开发记录_自学Python写爬虫程序爬取csdn个人博客信息
每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已... 于是萌生了一个想法: 想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来. 打算通过网络各种搜集资料 ...
- Java面试题之三
十一.谈谈final,finally,finalize的区别? 1.final:是修饰符,是一个关键字.修饰变量,如果是基本类型表示该变量的值不能修改:如果是引用类型表示该变量不能指向别的对象:修饰类 ...
- OTN交换&P-OTN有效减少100G网络成本(一)
近年来.网络运营商一直严重依赖基于ROADM的光传送设备,利用固定的点到点WDN联接.利用10G波长在整个城域网和广域网中汇聚及传送client业务.假设这些网络经过精细的设计规划,也能够合理.有效地 ...
- Python 第十二篇:HTML基础
一:基础知识: HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可 ...
- ISO C Random Number Functions
This section describes the random number functions that are part of the ISO C standard. To use these ...
- USACO Cow Pedigrees 【Dp】
一道经典Dp. 定义dp[i][j] 表示由i个节点,j 层高度的累计方法数 状态转移方程为: 用i个点组成深度最多为j的二叉树的方法树等于组成左子树的方法数 乘于组成右子树的方法数再累计. & ...
- CodeForces 276D – Little Girl and Maximum XOR 贪心
整整10个月后第二次搞这个问题才搞懂........第一次还是太随意了. 解题思路: 经过打表可得规律答案要么是0 要么是2的N次 - 1 要得到最大的XOR值,其值一定是2的N次 - 1 即在 l ...