题意:Snoopy想问下,若有n枚硬币,这n枚硬币的初始状态是任意的,求最小翻转次数x,满足无论任何初始状态,[刚好]翻转x次(不多少),
都能变成n枚硬币全为正或全为反。
思路:若n为偶数:
1: 若初始状态为偶数正面 + 偶数反面,要想变成全正或全反,翻转的次数必为偶数。
例如: ○○●●●● 则翻转 2,4,6,8……次均可。
2: 若初始状态为奇数正面 + 奇数反面,要想变成全正或全反,翻转的次数必为奇数。
例如: ○○○○○● 则翻转 1,3(先将●翻为○,再将任一个○翻两下),5,7……次均可。
因次,我们就无法得到一个确定的翻转次数x,让它能使任意初始状态的硬币变成全为正或全为反,因为若x为偶数,则无法满足例2,
若x为奇数,则无法满足例1。故应输出"No Solution!"。
若n为奇数:
1:对初始状态即全为奇数个正面(或反面)而言,翻转的次数为偶数(0,2,4...)或奇数(n,n+2,n+4...)(先将全部翻为另一面)。
2: 初始状态为偶数正面 + 奇数反面(偶数反面 + 奇数正面同理),分为翻转为全正面,和全反而两种情况:
全反面:例如: ○○○○●●● 则翻转4,6,8,10……次均可,其中最小为4。要保证对7枚硬币的任意初始状态都可行,则最小应为 7-1=6 ,
否则对 ○○○○○○● 无法实现。
全正面:必须翻转奇数次,由1知,奇数次翻转必然>=n。
因此,当n为奇数是,最少翻转次数为n-1。
源代码
1#include<iostream>
2
3using namespace std;
4
5int main()
6{
7 int n;
8 cin>>n;
9 while(n!=0)
10 {
11 if(n%2 == 0)
12 {
13 cout<<"No Solution!"<<endl;
14 }
15 else
16 {
17 cout<<n-1<<endl;
18 }
19 cin>>n;
20 }
21 return 0;
22}