cards number/2:<input id=cardnum value=26>
<button onclick="cal()">cal</button>
<div id=div1></div>
<script language="JavaScript">
<!--
function getScrambleNum(num){
var k, pos=2;
for(k=1;pos!=(num+1);k++){
pos = (pos<=num)? (pos*2-1) : (pos-num)*2;
}
return k;
}function cal(){
var n = parseInt(cardnum.value);
if(n<2) n = 2;
var str="";
for(var i=2;i<=n;i++){
str += "牌数:" + 2*i + " 洗牌次数:" + getScrambleNum(i) + "<br/>";
}
div1.innerHTML = str;
}
//-->
</script>
output:
牌数:4 洗牌次数:2
牌数:6 洗牌次数:4
牌数:8 洗牌次数:3
牌数:10 洗牌次数:6
牌数:12 洗牌次数:10
牌数:14 洗牌次数:12
牌数:16 洗牌次数:4
牌数:18 洗牌次数:8
牌数:20 洗牌次数:18
牌数:22 洗牌次数:6
牌数:24 洗牌次数:11
牌数:26 洗牌次数:20
牌数:28 洗牌次数:18
牌数:30 洗牌次数:28
牌数:32 洗牌次数:5
牌数:34 洗牌次数:10
牌数:36 洗牌次数:12
牌数:38 洗牌次数:36
牌数:40 洗牌次数:12
牌数:42 洗牌次数:20
牌数:44 洗牌次数:14
牌数:46 洗牌次数:12
牌数:48 洗牌次数:23
牌数:50 洗牌次数:21
牌数:52 洗牌次数:8

解决方案 »

  1.   

    只要计算移位就可以
    对任何一个牌位都成立,不一定要第二个:cards number/2:<input id=cardnum value=26>
    <button onclick="cal()">cal</button>
    <div id=div1></div>
    <script language="JavaScript">
    <!--
    function cal(){
    var str2 = "";
    var max = parseInt(cardnum.value)
    for(var n=2;n<=max;n++){
    seed = Math.round(Math.random()*(n-2));
    for (var i=1,ins=seed;ins!=seed||i==1;ins=((ins+1)*2>=n)?((ins+1)*2-n)-0.5:(ins*2+1)){i++;};
    str2 += "Card: " + 2*n + " time: " + (i-1) + "<br/>";
    }
    div1.innerHTML = str2;

    }
    //-->
    </script>
      

  2.   

    计算除了首尾两张牌之外的任一张牌的位置没有错,可是这是建立在这样一个基础之上的:有一张牌回到原位时所有的牌都回到原位了,但是这个前提要怎么被证明呢?第二个问题是要洗多少次牌能够简单的用一个表达式计算出来而不模拟移牌的过程吗?此外for (var i=1,ins=seed;ins!=seed||i==1;ins=((ins+1)*2>=n)?((ins+1)*2-n)-0.5:(ins*2+1)){i++;};并不是模拟了一个真正的牌的移动过程,看来好像是把牌的位置做了个映射,能解释一下映射的原则吗?
      

  3.   

    eum遇到什么倒霉事啦!!我知道我爽约是我不好!!下次不敢了帮你up一下吧。呵呵
      

  4.   

    这里有许多难解的数学问题,emu的洗牌问题也在其中。
    http://www.ocf.berkeley.edu/~wwu/riddles/hard.shtml
    SHUFFLING CARDS
      

  5.   

    http://www.ocf.berkeley.edu/~wwu/riddles/hard.shtml#shufflingCards
      

  6.   

    ??
    我的推论是显而易见的,
    从我的程序可以直接推导出既然必要,我再推详细一点:1)
    取1 到 n 之间任何一个牌做参照
    2)
    每次洗牌他到第一张牌之间将被插入(上次洗牌插入结果*2)+1个牌==》取任何两个牌A, B做参照,每次洗牌他们两个之间将被插入(上次洗牌插入结果*2)+1个牌==》如果以上两个牌的第二个(B)按第一个(A)和最顶上牌的距离取,则
    当第一个牌(A)相对于最顶上牌回到原位时,第二张牌(B)也回到原位3)
    而当以牌堆的第二张牌做B时,那么当B又变回第二张时,一次类推,三,四
    所有牌都回到原位,
    故,B回到原位的洗牌次数就是所求之值
    所以emu想要的多项式 就是以上程序列的 条件自增和((上次洗牌插入结果*2)+1) 的第一个回复周期:seed=0; //第一个参照牌对顶牌的距离是0,(即第二张牌)
    for (var i=1,ins=seed;ins!=seed||i==1;ins=((ins+1)*2>=n)?((ins+1)*2-n)-0.5:(ins*2+1)){i++;};
      

  7.   

    问的好,这正是问题所在由
    ins=((ins+1)*2>=n)?((ins+1)*2-n)-0.5:(ins*2+1)
    保证或者写清楚一点
    ins=ins*2+1;//(上次洗牌插入结果*2)+1个牌
    if (ins+1 > n) //那么这张牌的前边有ins+1张牌,当>n时表示过了中间点
    {
     var redu = (ins+1)-n //冗余
     var ins = redu-0.5 //改冗余强使下次洗牌,A距顶牌的距离成为redu*2,而为了满足ins*2+1的循环条件,逆向赋值为redu-0.5
    }
      

  8.   

    同意 wsj(骆驼) 的推论,可以接帖了。i=2*i+1  i<n/2
    i=2*i-n  i>=n/2
    现在的工作是如何证明不同范围里的先要统一公式
    因为1和n是不变的,可以把他们相接成环,头和尾合成一点
    所以上式就变为 i=(2*i+1)mod(n-1)所以在环中任意两者差距都是固定的 2dxps.这是后插法洗牌,有兴趣去研究一下前插法,呵呵
      

  9.   

    >跑场路过累坏了吧,Java&Web两边跑(还有哪里?)

    都是名利害人,注意身体哦
    :)
    真希望我能一次给你1421分10 karma 61166 保护环境,人人有责  
    11 beyond_xiruo 59745 此人已经离开,勿找!!!