组合数学题目

Knuthocean 2004-03-30 10:32:40
有一条实线段,它的长为2n个单位,自左到右标以-n,-(n-1),...-2,-1,0,1,2,...,
n.在-n,...,-2,-1处各放一个蓝钉,在1,2,...,n处各放一个白钉,而0处空着。白钉可以向左移动,蓝钉可以向右移动。当有一个空位时,其旁边的一个钉在可以移动的方向上移动一个单位来占有这一空位;当一种颜色的一个钉在另一种颜色一个钉的前面,而另一种颜色的那个钉的后面又有一个空位时,这个钉可跳过1个单位来占有这一空位。要求利用这两种运动,把蓝钉移到1,2,...,n的位置,把白钉移到-n,
...,-2,-1的位置。
用组合方法证明,对于任意下整数n,完成这一游戏需要n*n+2n次运动(移动和跳)。
...全文
75 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
aheadyes 2004-04-01
  • 打赏
  • 举报
回复
to dengsf
如果有时间的话。
不妨来个程序。
dengsf 2004-04-01
  • 打赏
  • 举报
回复
看了看,好象有错。

更正:
如果空格两边的颜色相同,则“根据上一步所走颜色”,先决定是否能够移动同色的钉子……
=======================去掉此句 ====异色
dengsf 2004-04-01
  • 打赏
  • 举报
回复
不好意思,是我想简单了……

我说说我的走法:
规则是根据 空格两边的钉子的颜色 和 上一步所走的钉子的颜色 来决定下一步走法的。当然,蓝色的只往右走,白色的只往左走。

初始时,空格在正中央(0处),上一步所走的颜色 设为其中一种。
如果空格两边的颜色不同,则根据“上一步所走颜色”来将同色的那钉子往它的方向移动。
如果空格两边的颜色相同,则“根据上一步所走颜色”,先决定是否能够移动同色的钉子;不行的话再移动另一种颜色的钉子。
如果空格的某一边是边界,则移动需要向该方向移动的钉子。比如在最左边时,移动白色的钉子。
当没有符合以上规则的移动时,表示已经结束了,退出。
Knuthocean 2004-04-01
  • 打赏
  • 举报
回复
谢谢
dengsf 2004-04-01
  • 打赏
  • 举报
回复
规则大致是如此,但还有一些细节要修改。

我写了个可读性很差的程序,测试了几个,觉得还可以,大家指正:

#include<stdio.h>
#include<stdlib.h>

enum Color{ BLUE, WHITE };
#define COLOROF(a) (a>0 ? WHITE : BLUE)
void display(int* a, int n);

int main(){
// - n ~ n
int n;
if( !scanf("%d", &n) ){
return 0;
}
getchar();

if( n < 1 || n > 10000 ){
printf("don't cheat me as a fool!");
return 0;
}

// represent the nails in the axis
int *a = NULL;
if(! ( a = (int*)malloc(sizeof(int)*(2*n+1)) ) ){
return 0;
}
for(int i=0; i<2*n+1; i++){
a[i] = i - n;
}
// initize position of the space
int position = n;
// last color
Color last = BLUE;

// routine
while(1){
display(a, n);
//left boundary
if( position == 0 ){
if( COLOROF(a[1]) == WHITE ){
a[0] = a[1];
a[1] = 0;
position = 1;
continue;
}else if(COLOROF(a[2]) == WHITE){
a[0] = a[2];
a[2] = 0;
position = 2;
continue;
}
break;
//right boundary
}else if( position == 2*n ) {
if( COLOROF(a[2*n-1 ]) == BLUE ){
a[2*n] = a[2*n-1];
a[2*n-1] = 0;
position = 2*n -1;
last = WHITE;
continue;
}else if( COLOROF(a[2*n-2]) == BLUE ){
a[2*n] = a[2*n-2];
a[2*n-2] = 0;
position = 2*n -2;
last = BLUE;
continue;
}
break;
//between the ones of the same color
}else if( COLOROF(a[position-1]) == COLOROF(a[position+1]) ){
if( COLOROF(a[position-1]) == BLUE ){
if( n+2 < 2*n +1 && COLOROF(a[position+2]) == WHITE ){
a[position] = a[position+2];
a[position+2] = 0;
position += 2;
last = WHITE;
continue;
}
a[position] = a[position-1];
a[position-1] = 0;
position -= 1;
last = BLUE;
continue;
}else{
if( position-2>=0 && COLOROF(a[position-2]) == BLUE ){
a[position] = a[position-2];
a[position-2] = 0;
position -= 2;
last = BLUE;
continue;
}
a[position] = a[position+1];
a[position+1] = 0;
position += 1;
last = WHITE;
continue;
}
break;
//between the ones of different colors
}else{
if( last == BLUE ){
if( COLOROF(a[position-1]) == BLUE ){
a[position] = a[position-1];
a[position-1] = 0;
position -= 1;
continue;
}else if( position-2>=0 && COLOROF(a[position-2]) == BLUE ){
a[position] = a[position-2];
a[position-2] = 0;
position -= 2;
continue;
}else if( position+2<2*n+1 && COLOROF(a[position+2])==WHITE ){
a[position] = a[position+2];
a[position+2] = 0;
position += 2;
last = WHITE;
continue;
}
break;
}else{
if( COLOROF(a[position+1]) == WHITE ){
a[position] = a[position+1];
a[position+1] = 0;
position += 1;
continue;
}else if( position+2<2*n+1 && COLOROF(a[position+2]) == WHITE ){
a[position] = a[position+2];
a[position+2] = 0;
position += 2;
continue;
}else if( position-2>=0 && COLOROF(a[position-2])==BLUE ){
a[position] = a[position-2];
a[position-2] = 0;
position -= 2;
continue;
}
break;
}
break;
}
}
getchar();
return 0;
}

void display(int* a, int n){
for(int i=0; i<2*n+1; i++){
printf("%3d ", a[i]);
}
printf("\n");
}
aheadyes 2004-04-01
  • 打赏
  • 举报
回复
dengsf的我觉得规则可以的,你自己到纸上画画.帮你谢谢 degsf:)
补充如下:
初始时,空格在正中央(0处),上一步所走的颜色 设为其中一种。
如果空格两边的颜色不同,则根据“上一步所走颜色”来将同色的那钉子往它的方向移动。
如果空格两边的颜色相同,先决定是否能够移动异色的钉子(也就是用跳的,往它的方向);
不行的话移动其中一颗,往自己的方向
如果空格的某一边是边界,则移动需要向该方向移动的钉子。比如在最左边时,移动白色的钉子。
当没有符合以上规则的移动时,表示已经结束了,退出。

不过要写出程序还是有点难度:)
dengsf 2004-04-01
  • 打赏
  • 举报
回复
步骤就是见一步走一步,白的总是往左走,蓝的总是往右走就是了。可能大家想得复杂了。

另:我不是学数学的,楼主太过奖了~~我一介菜鸟,只能在高手们的眼皮下混一些分来维持生计啊……
Knuthocean 2004-04-01
  • 打赏
  • 举报
回复
这个规则好像不行呀,我觉得要用回溯,只不过对于每次运动都有两种选择,要么蓝的动,要么白的动,总共有n*n+2n次运动,但是这样要做2^(n*n+2n)次,成npc问题了,dengsf你能解释一下你的方法的原理吗?
dengsf 2004-03-31
  • 打赏
  • 举报
回复
因为同色的钉子不能互相跨越,所以移动后,
-n的蓝钉必然在1处;
-n+1的蓝钉必然在2处;
...
-1的蓝钉必然在n处;
1的白钉必然到-n处;
...
n的白钉必然在-1处。

假如“跳”一步算"移动"两格,则全部排好后总的“移动”格数为 2n(n+1),
但在移动过程中,两种颜色的钉子要互相全部跨越,故总共的“跳”数为 n*n 次,
而每一“跳”相当于“移动”两格,
所以,在“移动”总数中,由“跳”所引起的“移动”步数为 2n*n,
所以,总的步数为 2n(n+1) - n*n = n*n + 2n.

PS:请问组合方法具体指什么?还有组合数学具体是研究哪方面内容的?好象都是些有趣的题目。
Knuthocean 2004-03-31
  • 打赏
  • 举报
回复
我也做不出来,高手帮帮忙
aheadyes 2004-03-31
  • 打赏
  • 举报
回复
顺便打印出移动步骤? 呵呵 偶做不出来:)
谁来做呀?
Knuthocean 2004-03-31
  • 打赏
  • 举报
回复
你学数学的吧,这么抽象的思维,好强呀!
Knuthocean 2004-03-31
  • 打赏
  • 举报
回复
我是菜鸟,说不清楚,你还是拿组合数学的介绍看一下吧!不好意思了!

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧