经典题目2 大家写算法

oDon 2006-03-29 10:26:18
某寄宿许小有15名女生,她们经常每天3人一行散布,问要怎么安排才能使每个女生与其他每个女生同一行散步,并恰好一周.
...全文
200 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wizardblue 2006-03-30
  • 打赏
  • 举报
回复
科克曼女生问题
waruqi 发表于 2006-3-13 19:55:00
1850年英国数学家科克曼在《女士和先生日报》上提出了一个问题,问题的叙

述是:某寄宿学校一位女教师每天带领她班上的15名女生去散步,她把这些女生按

3人一组分成5组,问能不能作出一个连续散步7天的分组计划,使得任意两个女生曾

被分到一组而且仅被分到一组。这就是科克曼女生问题,它是组合数学中一个著名

问题。

  科克曼本人给出了如下的分组方案:将15名女学生从1~15编号,则是满足条件

的分组。

  这里,科克曼给出的解并不是唯一的,除了在数学上认为是等价的简单调换排

列顺序的不同解外,还可以给出不少答案,当时人们曾猜测本质不同的分组方案有

13个。这一猜想过了100多年,到1974年才借助计算机得到解决。

  上述女生问题中女生的人数n如果被改变(由题意,n必需是3的整数倍),那么是

否还能有相应的散步方案呢?1971年,两位美国数学家发表论文证明了只有当n被6

除余3时才能构造出满足条件的方案。值得指出的是,中国数学家陆家羲事实上早在

1965年就解决了这个问题。作为中学物理教师的数学家陆家羲,在非常艰苦的条件

下,不但在科克曼女生问题上做出了一流的工作,而且得到了所谓“不相交斯泰纳

三连系大集定理”,这是现代组合学理论中具有里程碑意义的结果。为此,陆家羲

获得1987年中国国家自然科学一等奖。
treeroot 2006-03-30
  • 打赏
  • 举报
回复
up
Bingo2006 2006-03-30
  • 打赏
  • 举报
回复
谢谢
taolei 2006-03-30
  • 打赏
  • 举报
回复
事实上,在1-15中,a^b^c==0的不重复组合数也正好是P(15,2)/P(3,3)=35组,正好等于该题目的组合数7x5=35组。
taolei 2006-03-30
  • 打赏
  • 举报
回复
对于 c=a^b,(^是异或),可以得出
a^b^c==0
b=a^c
a=b^c

上面的答案的每一组都是a^b^c==0(c=a^b),只要a,b不重复,可以保证ac,bc都不会重复。
这样程序只需要搜索不重复的a和b。

Bingo2006 2006-03-30
  • 打赏
  • 举报
回复
int b;
int c= 0;
for(b=a+1;b<=15;b++)
{
if (!isMeet(a,b) && !isUsed(day,b) && !isUsed(day,a^b))
{
c = a^b;
break;
}
}

能说明一下这一段的逻辑吗?
Bingo2006 2006-03-30
  • 打赏
  • 举报
回复
nice
taolei 2006-03-30
  • 打赏
  • 举报
回复
public class Walk
{
static boolean[][] meet = new boolean[15][15];
static int[][][] answer = new int[7][5][3];
static boolean[][] used = new boolean[7][15];
private static boolean isUsed(int day,int x)
{
return used[day][x-1];
}
private static void setUsed(int day,int x,boolean b)
{
used[day][x-1]=b;
}
private static boolean isMeet(int a,int b)
{
return meet[a-1][b-1];
}
private static void setMeet(int a,int b,int c,boolean m)
{
meet[a-1][b-1] = m;
meet[a-1][c-1] = m;
meet[b-1][c-1] = m;
}
public static void main(String[] args)
{
long t0 = System.currentTimeMillis();
int day = 0;
int group = 0;
SEARCH:
for(;;)
{
int a=answer[day][group][0]+1;
for(;a<=15;a++)
{
if (!isUsed(day,a))
break;
}
int b;
int c= 0;
for(b=a+1;b<=15;b++)
{
if (!isMeet(a,b) && !isUsed(day,b) && !isUsed(day,a^b))
{
c = a^b;
break;
}
}
if (c == 0)
{
group --;
if(group == 0)
{
day--;
group = 4;
}
for(int i = 0; i<3; i++)
{
setUsed(day, answer[day][group][i], false);
}
setMeet(answer[day][group][0], answer[day][group][1], answer[day][group][2], false);
continue SEARCH;
}
answer[day][group][0] = a;
answer[day][group][1] = b;
answer[day][group][2] = c;
setUsed(day,a,true);
setUsed(day,b,true);
setUsed(day,c,true);
setMeet(a,b,c,true);
group++;
if (group == 5)
{
group = 0;
day++;
if (day == 7)
break SEARCH;
}
}
long t1 = System.currentTimeMillis();
for(day=0;day<7;day++)
{
for(group=0;group<5;group++)
{
for(int i=0;i<3;i++)
{
System.out.print(Integer.toHexString(answer[day][group][i]).toUpperCase());
}
System.out.print(" ");
}
System.out.println();
}
System.out.println("used time: " + (t1-t0) + "ms.");
}
}
123 48C 5AF 6BD 79E
145 28A 69F 3DE 7BC
167 29B 3CF 4AE 58D
189 347 5BE 2DF 6AC
1AB 356 2CE 49D 78F
1CD 572 68E 39A 4BF
1EF 246 38B 59C 7AD
used time: 0ms.
liuguangliang 2006-03-29
  • 打赏
  • 举报
回复
寄宿许小//what mean?
同一行散步?
oDon 2006-03-29
  • 打赏
  • 举报
回复
题意大致可以这样理解:假如A每天同不同的2人散步,一周2 * 7 =14 恰好与其他人都散过步.
如此,B C D...相仿.

62,629

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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