純美蘋果園

站务管理 => 跑團歷史區 => 歷史區 => 大杂烩 => 主题作者是: 大红龙 于 2013-07-07, 周日 21:47:31

主题: 个人谜题:第二期
作者: 大红龙2013-07-07, 周日 21:47:31
把 1-n 的数字各自写到2n张卡片上,然后按照规则进行排列:
两张相容数字的卡片之间,正好有相等于卡片上数字的卡片
比如1-3,那么 2 3 1 2 1 3 就是一种合适的排列

以一周时间为限,参加者找出n尽量大的排列。
*如果两个参赛者提供的排列n相同,那么以把排列组成一个数后较大的那个为胜利者。
比如1-3, 3 1 2 1 3 2 也是一种合适的排列,而且312132>231213,所以胜出。
*如果两人提供的排列完全一样,那么以先提出的参赛者为赢家。

出题人:笑语嗤天涯
无标准答案

奖励:10大福币
主题: Re: 个人谜题:第二期
作者: icefoggy2013-07-07, 周日 22:18:15
补充一下,我的错给大夫的题没写清楚

1-n是每个数2张,所以是2n张卡片

两张相同数字的卡片之间,正好有相等于卡片上数字的卡片

就是2张1之间有1张卡,2张2之间有2张卡……这样
主题: Re: 个人谜题:第二期
作者: 秦骓2013-07-07, 周日 23:56:32
1、2、1、3、2、8、9、3、10、12、6、11、5、7、8、4、9、6、5、10、4、7、12、11
主题: Re: 个人谜题:第二期
作者: poorlunch2013-07-13, 周六 05:46:36
 12    10    11     6     4     5     9     7     8     4     6     5    10    12    11     7     9     8     3     1     2     1     3     2
先来个一样的

个人以为这谜题其实是个编程问题,哼唧……
主题: Re: 个人谜题:第二期
作者: poorlunch2013-07-13, 周六 06:02:59
16, 14, 15, 11,  9,  7, 13,  4,  2, 12, 10,  2,  4,  7,  9, 11, 14, 16, 15,  8, 13, 10, 12,  5,  6,  1,  3,  1,  8,  5,  3,  6
结论,4的倍数最简单。
这大概是我愿意手动算的极限。剩下的交给电脑比较好……
主题: Re: 个人谜题:第二期
作者: 秦骓2013-07-14, 周日 01:03:48
2   3   4   2   6   3   8   4   20   9   19   6   18   7   17   8   16   5   15   9   14   7   13   5   12   1   11   1   10   20   19   18   17   16   15   14   13   12   11   10

虽然似乎不是很难……但是推20还是花了半小时多orz
主题: Re: 个人谜题:第二期
作者: poorlunch2013-07-14, 周日 02:46:25
半小时编了个程序。
 20, 18, 19, 15, 13, 17, 10,  8, 16,  5,  2, 14, 11,  2, 12,  5,  8, 10, 13, 15, 18, 20, 19, 17, 11, 16, 14, 12,  9,  7,  3,  4,  6,  1,  3,  1,  4,  7,  9,  6 这是20的。

60, 58, 59, 55, 53, 57, 50, 56, 47, 45, 54, 42, 40, 52, 37, 51, 34, 32, 49, 29, 48, 26, 24, 46, 21, 19, 44, 16, 43, 13, 11, 41,  8,  6, 39,  3,  1, 38,  1,  3,  6,  8, 11, 13, 16, 19, 21, 24, 26, 29, 32, 34, 37, 40, 42, 45, 47, 50, 53, 55, 58, 60, 59, 57, 56, 54, 52, 51, 49, 48, 46, 44, 43, 41, 39, 36, 38, 35, 31, 28, 33, 27, 23, 20, 30, 25, 18, 14, 12,  9,  4,  5,  7,  2, 22,  4,  2,  5, 17,  9,  7, 12, 14, 15, 20, 18, 23, 10, 28, 27, 31, 25, 36, 35, 33, 30, 17, 22, 10, 15
n=60 ,用时8.7s。

 72, 70, 71, 67, 65, 69, 62, 68, 59, 57, 66, 54, 52, 64, 49, 63, 46, 44, 61, 41, 60, 38, 36, 58, 33, 31, 56, 28, 55, 25, 23, 53, 20, 18, 51, 15, 50, 12, 10, 48,  7, 47,  3,  1, 45,  1,  3, 43,  7, 10, 12, 15, 18, 20, 23, 25, 28, 31, 33, 36, 38, 41, 44, 46, 49, 52, 54, 57, 59, 62, 65, 67, 70, 72, 71, 69, 68, 66, 64, 63, 61, 60, 58, 56, 55, 53, 51, 50, 48, 47, 45, 43, 42, 40, 37, 35, 39, 32, 34, 29, 27, 24, 22, 19, 17, 14, 11, 16,  8, 30,  5,  9,  6, 13, 26, 21,  5,  8, 11,  6, 14,  9, 17, 19, 16, 22, 24, 13, 27, 29, 32, 35, 37, 34, 40, 42, 39, 21,  4,  2, 30, 26,  2,  4
n=72,用时311s。


matlab确实不是啥速度快的程序。可惜手里没有c或者fortran……

ps:如果有人足够闲的话我可以提供源码以供优化以及转编程语言……
主题: Re: 个人谜题:第二期
作者: 秦骓2013-07-14, 周日 10:14:35
我去……【虽然我想用Matlab编程……不过在旅游的表示没有精力啊……

【matlab不适合循环,更适合矩阵……
主题: Re: 个人谜题:第二期
作者: poorlunch2013-07-14, 周日 20:48:46
matlab是解释型语言。即使算矩阵也只是方便而不是快。
尤其这种深度优先回溯法,编译型语言大概可以快个一倍?

顺手把程序贴出来。

function mainfun()
global n numuse numpos numall

n = 72;
numuse = zeros(1,n);
numpos = zeros(2,n);
numall = zeros(1, 2*n);

unfinished  = 1;
currentnumpos = 0;
currentnumindex = n;

tic
while unfinished
    i = getnextpos();
%      currentnumindex
%     numall
    num = getnextnum(currentnumindex);
   
    if i+num+1 > 2*n || ((numall(i+num+1) ~= 0) && (currentnumindex == 1)) || (num == 0)
        % get back one number
        if currentnumpos <1
            disp('no solution!');
            break
        end
        numall(numpos(2,currentnumpos)) = 0;
        numall(numpos(2,currentnumpos)+ numpos(1,currentnumpos)+1) = 0;
        numuse(numpos(1,currentnumpos)) = 0;
        currentnumindex = numpos(1,currentnumpos)-1;
        numpos(1,currentnumpos) = 0;
        numpos(2,currentnumpos) = 0;
        currentnumpos = currentnumpos - 1;
    elseif numall(i+num+1) ~= 0
        % current number add 1
        currentnumindex = currentnumindex - 1;
    else
        % add number and go to next
        numuse(num) = 1;
        numall(i) = num;
        numall(i+num+1)=num;
        currentnumpos = currentnumpos+1;
        numpos(1,currentnumpos) = num;
        numpos(2,currentnumpos) = i;
        currentnumindex = n;
    end

    if currentnumpos == n
        % solution found
        numall
        unfinished=0;
    end
end
toc

function nextpos=getnextpos()
global n numuse numpos numall
nextpos = 0;
for i=1:2*n
    if numall(i) == 0
        nextpos = i;
        break
    end
end
return

function nextnum=getnextnum(currentnumindex)
global n numuse numpos numall
nextnum = 0;
for i=currentnumindex:-1:1
    if numuse(i) == 0
        nextnum = i;
        break
    end
end
return
主题: Re: 个人谜题:第二期
作者: icefoggy2013-07-15, 周一 00:06:58
好吧虽然用编程解不是我的本意,但是胜利者就是便当了

其实这个谜题稍微多写几个连续的就能找到递推的方法,而且像 秦骓 第一次写出的那个数列,倒一倒就是一个更大的答案。
如果所有人都笔算,很容易从别人的答案中找到一个更大的答案
我本意是参赛者在递推和捡漏间,争夺出一个最大答案
不过一方面参加的人数少,一方面变成了编程求解= =,就这样吧,我就当积累经验了
主题: Re: 个人谜题:第二期
作者: 秦骓2013-07-15, 周一 00:21:06
附录:

这个数列叫:挑剔数列……