1. 问题:
1) 问题描述:
有m个正面朝上的硬币,每次必须翻5个,求翻几次后可以使硬币全部正面朝下。
2) 输入格式:
仅有的一个数字是这摞硬币的枚数m,5<m<1000的整数。
3) 输出格式:
为了使这些硬币中的每一枚都是正面朝下所必需翻的次数。
4) 输入输出样例:
输入样例:
6
输出样例:
6
2. 分析
1) m=6的时候:
2) m=7的时候:
3) m=8的时候:
4) 当m>=9的时候:
所有数字可以用5k,5k+1,5k+2,5k+3,5k+4来表示,k表示顺着翻k次将硬币都翻为正面朝下,定义f(m)为最少步数。
a、若m=5k,则f(5k)=k。
b、若m=5k+1,先讨论左边8个:
00000000
11111000
11100111
翻2次,使得8个中有6个被翻过来,一共剩5k+1-8+2=5k-5个,再顺着翻k-1次即可,所以f(5k+1)=k-1+2=k+1
c、 若m=5k+2,先讨论左边6个:
000000
111110
100001
翻2次,使得6个中有2个被翻过来,一共剩5k+2-2=5k个,顺着翻k次即可,所以f(5k+2)=k+2
d、 若m=5k+3,先讨论左边9个:
000000000
111110000
111101111
翻2次,使得9个中有8个被翻过来,一共剩5k+3-8=5k-5个,顺着翻k-1次即可,所以f(5k+3)=k-1+2=k+1
e、 若m=5k+4,先讨论左边7个:
0000000
1111100
1100011
翻2次,使得7个中有4个被翻过来,一共剩5k+4-4=5k个,顺着翻k次即可,所以f(5k+4)=k+2
3. 解答
program demo;
var
m:integer;
begin
readln(m);
if m=6 then begin writeln(6); exit; end;
if m=7 then begin writeln(3); exit; end;
if m=8 then begin writeln(4); exit; end;
if m mod 5=0 then begin writeln(m div 5); exit; end;
if (m mod 5=1)or(m mod 5=3) then begin writeln(m div 5+1); exit; end;
if (m mod 5=2)or(m mod 5=4) then begin writeln(m div 5+2); exit; end;
end.
转载于:https://blog.51cto.com/huobumingbai/304397