前言

本文介绍蓝桥杯题目——翻硬币的一种无需对字符串进行操作的解法及该解法所包含的思想。

题目信息

桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

比如,可能情形是:**oo***oooo

如果同时翻转左边的两个硬币,则变为:oooo***oooo

现在的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

我们约定:把翻动相邻的两个硬币叫做一步操作。

输入格式

两行等长的字符串,分别表示初始状态和要达到的目标状态。

输出格式

一个整数,表示最小操作步数

数据范围

输入字符串的长度均不超过100。

数据保证答案一定有解。

输入样例

**********
o****o****

输出样例

5

解题思维

假设这样一组输入:

**********
o*********

因为每次要翻动两个硬币,想单独地把第一个硬币变成o,就一定会带来副作用(影响其他的硬币),即使这个硬币不在第一个位置。

也就意味着我们用任何方法也不能单独地将一个硬币反转,必须要有另一个同样需要反转的硬币。

因此,题目给的数据中,两个字符串不同之处的数量一定为偶数,否则第一个字符串无论怎样翻转也不能达到第二个字符串(目标)的状态。

思想(1)

因为每个硬币只有正、反两种可能,所以一组硬币(一次反转两个,因此称两个硬币为一组)如果已经被反转一次了,如果再将其反转回来,就会使得这两次反转都无意义。

一般地说,就像同类费解的开关和点灯这种每个位置只有两种选择的问题一样,同一个位置,操作两次,都是无意义的。

在本题中,同一组硬币,我们最多只会翻转一次,拿题目给出的数据举例,我们的目的是把一号和六号的硬币反转成为o。



第一次,我们反转前两个。

第二次,我们的目的是将2号的o变成*,因为1和2这一组已经被反转一次,因此第二次我们只能选择2和3这一组。



第三次,目的是反转3号,但23这一组已被反转,因此只能反转34这一组。



第四次,同理,只能反转45这一组。



第五次,当反转56这一组时会发现,反转后的状态刚好就是我们所求的状态,这正是刚才解题思维中说到的有另一个需要反转的硬币(6号)来弥补之前的硬币(1号)反转所带来的副作用。



此时你会发现,从1号到6号,其包含的每一组我们都反转了一次,其间的每一个硬币我们都反转了两次,只有这样才能刚刚好使得两个不同之处变为相同。

原因: 其间的硬币反转两次,相当于没反转;其包含的最开始和最后一个硬币,只反转了一次,因此改变的正反面。

因此,对于这题我们只需要找到每两个不同之处之间有多少个硬币,就可以推算出将这两个不同之处同时反转,需要消耗几步。

思想(2)

如果做题时没有发现每同时反转两个不同之处所消耗的步数等于其间的硬币数+1这条规律,那么大概率会用模拟法做,那无疑就使代码更加复杂。

一数曾说过下文类似的一句话:像这种看起来很简单,但是数据很大,暴力法做不了的;看起来像一般性题,但一般性方法做不了的,通常在题目中都有隐含的条件没有发现,一旦发现,此类题目将特别简单。

代码实现

首先,写出主函数和用来输入输出的函数。

int main()
{
char str1[120];
gets_s(str1);
char str2[120];
gets_s(str2); int time =sta(str1, str2);
printf("%d", time);
return 0;
}

随后对sta函数进行实现。

我们要统计的数目是每一组不同之处之间的硬币数,因此设置一个变量flag,当其为1时代表遇到了一组不同中的第一个不同,此时开始统计数目,当其为-1时,代表遇到了一组不同中的第二个不同,此时不统计数目。

int sta(char* str1, char* str2)
{
int count = 0;
int flag = -1;//是否开启统计
while (*str1 != '\0')
{
if (*str1 != *str2)
{
flag *= -1;
}
if (flag==1)
{
count++;
}
str1++;
str2++;
}
return count; }

可见,代码中并没有对字符串的任何操作,极大地减轻了代码量。

思想(3)

在实现sta函数时,并没有将flag的初始值设为0,而是设为了-1。

这样做可以在开启或关闭统计时直接让其乘以-1即可,不用再判断flag此时是哪一种情况。

亦或者在用模拟法的时候,* 表示正面,o 表示反面,那么你在反转时要先判断当前位置是 * 还是 o,但是如果用1表示正面,-1表示反面,你在反转的时候不需要判断,只需要让其乘以-1即可。

亦或者像费解的开关那样,用1表示开,0表示关,这样你在打开或关闭的时候,只要让其赋值为自身的非即可,不必额外判断当前的情况。


感谢您的阅读与耐心~ 如有错误烦请指出~ 谢谢

蓝桥杯题目——翻硬币无需修改‘*’与’o‘的特殊解法及其所包含的思想的更多相关文章

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

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

  2. 2018年第九届蓝桥杯题目(C/C++B组)汇总

    第一题 标题:第几天 2000年的1月1日,是那一年的第1天. 那么,2000年的5月4日,是那一年的第几天? 注意:需要提交的是一个整数,不要填写任何多余内容. 解题思路: 1.  判断2月有几天, ...

  3. ACM蓝桥杯之换硬币问题

    题目描述: 想兑换100元零钱,有1元.2元.5元.10元四种面值,总有多少种兑换方法? 解题思路: 本题可以采用多种方法求解.最容易理解的应该就是暴力穷举和递归求解.那么本文主要介绍这两种解法. 暴 ...

  4. 树形dp|无根树转有根树|2015年蓝桥杯生命之树

    2015年蓝桥杯第十题--生命之树(无根树dfs) ①暴力解法:枚举子集(选点) + dfs判断连通性(题目要求连通)满足上面两个条件下找出最大值权值和 ②dfs无根树转有根树,递归找最优 先学习无根 ...

  5. 乘积最大|2018年蓝桥杯B组题解析第十题-fishers

    标题:乘积最大 给定N个整数A1, A2, ... AN.请你从中选出K个数,使其乘积最大. 请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数. 注意,如果X ...

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

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

  7. 蓝桥杯 历届试题 PREV-34 矩阵翻硬币

    历届试题 矩阵翻硬币   时间限制:1.0s   内存限制:256.0MB 问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬 ...

  8. Java实现 蓝桥杯 历届试题 翻硬币

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

  9. 2012年 蓝桥杯预赛 java 本科 题目

    2012年 蓝桥杯预赛 java 本科 考生须知: l  考试时间为4小时. l  参赛选手切勿修改机器自动生成的[考生文件夹]的名称或删除任何自动生成的文件或目录,否则会干扰考试系统正确采集您的解答 ...

  10. 2018年蓝桥杯A组C/C++决赛题目

    2018年蓝桥杯A组C/C++决赛题目 2018年蓝桥杯A组C/C++决赛题解     1:三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5 ...

随机推荐

  1. 计算1+2!+3!+...+n!的和

    计算1+2!+3!+...+n!的和 Code 点击查看代码 #include<iostream> #include<vector> using namespace std; ...

  2. Web初级——CSS3

    CSS Cascding Style Sheet(层叠级联样式表) 1.前言 1.1CSS优势 内容和表现分离 可以实现CSS代码复用 利用SEO,容易被搜索引擎收录 1.2CSS导入方式 <! ...

  3. Java学习笔记:2022年1月13日(其一)

    Java学习笔记:2022年1月13日(其一) ​ 摘要:这篇笔记主要讲解了Java中的自定义类.以及构造一个类时所需要了解的一些重点知识. 目录 Java学习笔记:2022年1月13日(其一) 1. ...

  4. Java 进阶P-6.4+P-6.5

    狐狸和兔子 狐狸和兔子都有年龄 当年龄到了一定的上限就会自然死亡 狐狸可以随即决定在周围的兔子中吃一个 狐狸和兔子可以随即决定生一个小的,放在旁边的空的格子里 如果不吃也不生,狐狸和兔子可以随机决定走 ...

  5. C-01\编译器和链接器以及真正的入口函数

    编译器: 工具 编译器 路径 VC++6.0 CL.EXE(一段shell)只负责分析命令行参数,真正功能实现在C1.DLL.C1XX.DLL.C2.DLL C:\Program Files (x86 ...

  6. 微服务学习计划——SpringCloud

    微服务学习计划--SpringCloud 在学习并掌握了众多基础框架之后,我们的项目繁杂且难以掌握,那么我们就需要开启一门新的课程,也就是我们常说的微服务架构 随着互联网行业的发展,对服务的要求也越来 ...

  7. Vim-Adventures 有趣的Vim小游戏

    入门介绍 Vim-Adventures是一个让初学者练习如何使用 Vim 的小游戏.它一共有 TODO 个 关卡,每个关卡都对应不同的 Vim 练习.一进网页我们可以看到这个画面: 点进去后就自动来到 ...

  8. 【译】.NET 7 中的性能改进(三)

    原文 | Stephen Toub 翻译 | 郑子铭 PGO 我在我的 .NET 6 性能改进一文中写了关于配置文件引导优化 (profile-guided optimization) (PGO) 的 ...

  9. Slave_IO_Running: Connecting--一种问题的解决方案

    主要有三个原因: 1.网络不同 2.密码不对 3.pos不对 这里只介绍我碰到的问题--不能远程连接数据库.即在从机上对主机进行以下命令 mysql -u**** -p**** -h192.168.* ...

  10. JZOJ 4496. 【GDSOI 2016】第一题 互补约数

    \(\text{Problem}\) 求 \[\sum_{i=1}^n \sum_{d|n} \gcd(d, \frac{i}{d}) \] 有 \(n \le 10^{11}\) \(\text{A ...