欢迎访问我的新博客:http://www.milkcu.com/blog/
原文地址:http://www.milkcu.com/blog/archives/1371171420.html
标题:翻硬币 - 蓝桥杯
内容:2013年第四届蓝桥杯全国软件大赛预赛,第8题。
作者:MilkCu
题目描述
题目标题:翻硬币
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oo***oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
程序输入:
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
程序输出:
一个整数,表示最小操作步数
例如:
用户输入:
**********
o****o****
程序应该输出:
5
再例如:
用户输入:
*o**o***o***
*o***o**o***
程序应该输出:
1
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
分析
该程序主要包括输入和处理两部分,属于字符串的处理。
当然这各题有个漏洞,下面的情况无法正常输出
*o**
****
也就是不同个数为奇数个的时候
在处理的时候,这种情况不予考虑。
代码实现
# include <stdio.h> int turn(int a[], int b[]) { int n = 0; for(int i = 0; a[i] != EOF; i++) { if(a[i] == b[i]) { continue; } else { b[i + 1] = (b[i + 1] == '*' ? 'o' : '*'); n++; } } return n; } int main(void) { int a[1000]; int b[1000]; int c; int i; i = 0; while((c = getchar()) != '\n') { a[i++] = c; } a[i] = EOF; i = 0; while((c = getchar()) != '\n') { b[i++] = c; } b[i] = EOF; printf("%d\n", turn(a, b)); }
最后答案
见上。
语言扩展
break语句
不通过循环头部或尾部的条件测试跳出循环,有时是挺方便的。break语句可用于从for、while与do-while等循环中提前退出,就如同从switch语句中提前退出一样。
continue语句
continue语句用于是for、while或do-while语句开始下一次循环的执行。在while和do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环中,则意味着使控制转移到递增循环变量部分。continue语句只用于循环语句,不用于switch语句。
如果不使用continue语句,则可能需要把测试颠倒过来或者缩进另一层循环,这样做会使程序的嵌套更深。
参考资料
- 《C程序设计语言》,Kernighan,Ritchie,2版,64页;
(全文完)