翻硬币解析Word下载.docx

上传人:b****5 文档编号:21763794 上传时间:2023-02-01 格式:DOCX 页数:9 大小:19.51KB
下载 相关 举报
翻硬币解析Word下载.docx_第1页
第1页 / 共9页
翻硬币解析Word下载.docx_第2页
第2页 / 共9页
翻硬币解析Word下载.docx_第3页
第3页 / 共9页
翻硬币解析Word下载.docx_第4页
第4页 / 共9页
翻硬币解析Word下载.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

翻硬币解析Word下载.docx

《翻硬币解析Word下载.docx》由会员分享,可在线阅读,更多相关《翻硬币解析Word下载.docx(9页珍藏版)》请在冰豆网上搜索。

翻硬币解析Word下载.docx

  elsebegin

  

 

   d:

=2*m+1;

     t:

=2;

     i:

=1;

     flag:

=False;

     repeat

      if(t=1)then

       begin

        solve:

=②

        flag:

=True;

       end

      elseif(③)then

       begin

        solve:

=i*m-1;

        flag:

      endelset:

=④;

      i:

=i+1;

     untilflag;

  end

 end;

 begin

  read(m);

  if((m>0)and(m<1000))then

   writeln(⑤);

 end.

我们把每一次的翻转称为一次“小翻转”,从顶上开始连续翻n次称为一次“大翻转”。

最后翻到全是正面朝上的状态时,如果用了a次大翻转和b次小翻转,那么总的翻转次数是a*n+b。

我们研究一次大翻转的置换结构。

自底向上(为方便我们实际上用自左向右),用1,2,3,...,n标记n个硬币,用a'

表示硬币a的反面朝上状态。

我们还在这一摞硬币的右端放一面镜子,那么,初始状态是:

('

|'

表示镜子的位置)

[1234...n-1n|n'

(n-1)'

...4'

3'

2'

1'

]

经过一次大翻转后,成为:

[246...5'

|135...6'

4'

这个变换很有规律。

只要令a'

=-a,可以看出,一次大翻转就是把编号为c的硬币变换到c/2(mod2n+1)(?

)的位置。

看其逆变缓将更明显。

(偶数是的,奇数应是n-(c+1)/2(mod2n+1)

显然,如果2^m=1(mod2n+1),那么经过m次大翻转后,所有硬币都归到原位而且面朝上。

此时共用了m*n次小翻转。

同样地,如果2^m=-1(mod2n+1),那么经过m次大翻转后,所有硬币都将归到原位,并且正面朝下。

如果不做最后那个大翻转的最后那个n个硬币翻过来的小翻转,那么就能得到正面全朝下的状态,此时需要m*n-1次小翻转。

剩下的问题是,证明只有上面所述两种情况下才会出现正面全朝上的局面。

需要证明几个事实:

1)进行任意次大翻转后,再进行0<

b<

n-1次小翻转,那么不可能出现全部硬币正面朝上的局面。

(即要出现正面全朝上的情况,必然有b=0或b=n-1.)

2)如果经过m次大翻转后全部硬币正面朝上,那么确实每个硬币都回到了原来的位置。

3)如果经过m次大翻转后全部硬币正面朝下,那么确实每个硬币都回到了原来的位置。

2)与3)比较容易证明,证法也类似。

1)证起来麻烦一些。

证明嘛……就不写了。

翻硬币问题的多种求解

一个关于翻硬币的问题,

一摞硬币共有m枚,每一枚都是正面朝上。

输入:

  仅有的一个数字是这摞硬币的枚数m,0<

m<

1000。

  某单元格输入:

  某单元格等于:

下面是我自己的两种解法

[解法一]

思路:

每一轮的翻转后,能得到每一枚硬币当前的位置的位置,如果硬币重新回到原先的位置(基数个硬币时)或者相反的位置(偶数个硬币时),就的到了求解。

//查找每轮循环后的位置

intGetTurnAfterPos(intn,intturn,intm)

{

intTurnNum;

//每轮翻转次数

intTurnAfterPos;

//每轮循环后的位置

TurnNum=turn-n+1;

if(TurnNum%2==0)//为偶数次循环

TurnAfterPos=n+TurnNum/2;

else 

//为奇数次循环

TurnAfterPos=(TurnNum+1)/2;

returnTurnAfterPos;

}

//每一轮翻转之后的位置:

intsolve(intturn,int*CurrentPos,intm)

if(turn==0)

 

return0;

for(inti=0;

i<

turn;

i++)

intRetNum=GetTurnAfterPos(i+1,turn,m);

CurrentPos[RetNum-1]=CurrentPos[m+i];

for(i=0;

m;

CurrentPos[i+m]=CurrentPos[i];

return0;

intmain()

intm=30;

//硬币总数 

int*CurrentPos=newint[m*2];

intn=0;

//翻转次数

boolflag=false;

do

n++;

m*2;

i++)

CurrentPos[i]=i%m+1;

intx=n/m;

inty=n%m;

for(i=0;

x;

solve(m,CurrentPos,m);

solve(y,CurrentPos,m);

printf("

%d"

CurrentPos[i]);

//solve(5,CurrentPos,m);

/n"

);

if(CurrentPos[i]!

=i+1)

break;

if(i==m-1&

&

n>

1)

flag=true;

while(!

flag);

if(m%2==0)

翻转的总次数是:

%d/n"

n-1);

else

n);

delete[]CurrentPos;

[解法二]

不管硬币的次序,只是记住每次的翻转和交换,硬币的初始状态都是TRUE,每个COIN经过多伦的翻转后都变回TRUE,那么就求出了解,这是最简单的思路。

voidsolve(intm)

bool*CurrentSurface=newbool[m];

for(inti=0;

CurrentSurface[i]=true;

intturnTimes=0;

boolbSuccess=false;

do

{

for(intj=0;

j<

(i+1)/2;

j++)

//turnCoin(j,i-j+1);

booltemp=CurrentSurface[j];

CurrentSurface[j]=!

CurrentSurface[i-j];

CurrentSurface[i-j]=!

temp;

}

if((i+1)%2==1)

CurrentSurface[i/2]=!

CurrentSurface[i/2];

turnTimes=turnTimes+1;

bSuccess=true;

for(intn=0;

n<

n++)

if(CurrentSurface[n]==false)

bSuccess=false;

break;

if(bSuccess)

}while(!

bSuccess);

printf("

turnTimes);

delete[]CurrentSurface;

intCoinCount=1;

while(CoinCount>

0)

请输入硬币的总数:

"

scanf("

%d"

&

CoinCount);

solve(CoinCount);

网上还有几种解法,也同时列了出来:

[解法三]

这个是最难理解的一个算法,因为没有注释,呵呵。

intsolve(int 

m);

intmain() 

int 

do 

 

&

m);

if(m 

>

<

1000) 

%d/n/n"

solve(m));

while(m 

1000);

solve(int 

m) 

I, 

t, 

d, 

s=- 

1;

//翻转的次数 

int 

flag;

//如果只有一枚硬币,翻两次就能达到目标

if(m==1) 

s=2;

d=2 

//确定硬币是经过偶数次翻转还是奇数次翻转

t=2;

//表示一个COIN必须翻转偶数次,才能从正面继续翻回到正面。

I=1;

//翻转的轮数,每轮为从1翻转到m

flag=0;

//退出循环标志,翻转完成标志

%d:

d);

/tt(%d) 

%d, 

/t 

s:

%3d, 

%3d/n"

m, 

1);

if(t==1) 

//

s=I*m;

flag=1;

elseif(t==2*m) 

s=I*m-1;

t=(t 

2) 

d;

I=I+1;

s, 

return 

s;

}

[解法四]

设 

题设的从1到n的翻转为一轮番转,位置 

pos, 

turnNum 

为位置pos所需要的翻转次数 

,假设有5个硬币,我们按其位置分别编号 

1,2,3,4,5 

经过一轮翻转后,变成了5,3,1,2,4;

可以看到原来1位置的硬币现在到了3。

这一点说明一轮翻转过后,pos的排列是有规律的,另外,任意位置上的元素的翻转次数为turnNum 

num+1-pos;

由以上分析得到了,任意位置pos,经过一轮番转后的位置变为了new_pos 

num/2 

turnNum/2 

turnNum%2*turnNum 

所以,可以由上式计算出new_pos。

那么,如果new_pos也为1的话,则所有的硬币都回到了原来的位置,且都朝正面。

#include 

"

stdio.h"

int 

solve(int 

m) 

0;

pos,turnNum,temp,s;

if(m 

== 

1) 

2;

else 

pos 

do 

I++;

temp 

m+1-pos;

+= 

temp;

m/2 

pos/2 

temp%2*(pos/2)*2;

}while(pos!

=1);

I*m 

turnNum%2;

//the 

sum 

of 

times 

return 

main() 

scanf("

the 

is 

:

solve(m));

}while(m 

!

-1);

[解法五]

思路:

直接模拟

#include<

iostream>

#include<

stdlib.h>

#define 

swap(a,b){int 

t=!

a;

a=!

b;

t;

n;

flag[1000];

bool 

isright() 

for(int 

i=0;

i<

n;

i++) 

if(!

flag[i]) 

false;

true;

turncoin() 

total 

while

(1) 

total%n;

i,j;

for( 

i=0,j=k;

=j;

i++, 

j--) 

swap(flag[i],flag[j]);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1