社区
Java SE
帖子详情
一道计算题
zhuguangyuan
2007-09-13 06:21:28
100个人做游戏,让100个人围成一个大圈,每个人分别报数,报数方式是从1开始到7结束,报到7的人退出游戏,余下的人继续报数,从推出的下一个人开始从新报1 ,报7的人退出,一次循环,找出最终获胜选手。
大家试一下!挺有意思!
...全文
732
26
打赏
收藏
一道计算题
100个人做游戏,让100个人围成一个大圈,每个人分别报数,报数方式是从1开始到7结束,报到7的人退出游戏,余下的人继续报数,从推出的下一个人开始从新报1 ,报7的人退出,一次循环,找出最终获胜选手。 大家试一下!挺有意思!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
26 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
sea_force
2007-09-26
打赏
举报
回复
顶你上去
sniperhuangwei
2007-09-15
打赏
举报
回复
对于数2出列的可以看下这个方法。
int ju(int n)
{
return (n == 1 ? 1 : (n%2 == 0 ? 2*ju(n/2)-1 : 2*ju(n/2)+1) );
}
capturesource
2007-09-15
打赏
举报
回复
sniperhuangwei() ( ) 信誉:99 2007-9-14 10:59:37 得分: 0
java编程当真不需要考虑效率吗?
对这种简单的问题也动用封装好的库.
字符的连接操作导致了多少字符的移位,被拷贝,有没有考虑过.
-------------------------------------------------------------
没有考虑!我只考虑编程要的是思想,要灵活,我只是提供另外的思路而已.
对于使用封装好的库而言,我觉得没有什么大不了的,有就用嘛,不然他封装了是放在那里好看的?
没有必要为每一个功能自己去开发更多的类啊...
[杀鸡就要用牛刀,打蚊子就喜欢用大炮]
我只是菜鸟,我追求的是随便找几只虫吃饱就好!
chuter
2007-09-15
打赏
举报
回复
说一下我的思路:就是计算最后活下来那个人的位置
一个for循环计算出每次出局人的位置,描述如下
begin = 0
for(i=1; i<n; i++) {
kill[i] = (begin+7)%n;
begin = (kill[i]+1)%n;
}
最后留下来的那个人位置肯定是0,那么逆着计算他的位置:
pos = 0
for(i=n-1; i>=1; i--) {
if(kill[i]<=pos)
pos += 1
}
这样就计算出那个人的位置了
kaiy_ai
2007-09-15
打赏
举报
回复
三级考试抽到这个题 过了 不过不想在编了 网上又都是~~~ 顶一下吧
sniperhuangwei
2007-09-15
打赏
举报
回复
很好的实现,不过m=1时无法给出正确结果。
capturesource
2007-09-15
打赏
举报
回复
今天找到高人的算法了!
int fun(int n, int m) {
int i, r = 0;
for (i = 2; i <= n; i++)
r = (r + m) % i;
return r+1;
}
不过我看不明白,但是运行结果没有问题.
chen_zx
2007-09-15
打赏
举报
回复
#define nmax 50
main()
{
int i,k,m,n,num[nmax],*p;
printf("please input the total of numbers:");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;
i=0;
k=0;
m=0;
while(m<n-1)
{
if(*(p+i)!=0) k++;
if(k==3)
{ *(p+i)=0;
k=0;
m++;
}
i++;
if(i==n) i=0;
}
while(*p==0) p++;
printf("%d is left\n",*p);
}
顶一下
qingyuan18
2007-09-15
打赏
举报
回复
这不约瑟夫环么?老掉牙的问题了,用链表来做吧
zhangguiwu
2007-09-14
打赏
举报
回复
好象学C的时候做过
Lisliefor
2007-09-14
打赏
举报
回复
while(array.size()>1) {
int beginNum=0;
for(int i=beginNum;i<array.size();i++) {
Person p =array.get(i);
count = p.callNum(count);
// 喊道7,出局 计数从新开始
if(count == 7) {
array.remove(i);
count = 0; // 计数归0
}
}
beginNum=array.size()/7+1;
}
你不觉得for循环结束后,虽然beginNum被赋值了,但在下一次while循环开始,int beginNum = 0又将它的值改为了0。这个地方的“beginNum=array.size()/7+1;”没有任何意义!!
不信可以输出一下。
Lisliefor
2007-09-14
打赏
举报
回复
count是一直传递的,开始元素有100个,当到第7个人时,出局,array移除这个元素,而这个时候,array的size只有99了(ArrayList以数组方式存储数据,它允许直接按序号索引元素,但插入或删除元素涉及到数组元素的移动的内存操作,这个是它性能上的差距,比起前面几位兄弟的算法,要消耗资源)。
这时,可能array的次序已经被打乱,因为第7个元素被删除了,第8个元素现在在第7个元素的位置上。但person类的name是不会变的。count归0,for循环并没有结束,继续.....
当到完成99次比较,我们的count相对于这些类始终是保持“同步”,因为上一次报数,会被传给下一个即将报数者。虽然每次while循环都是从第一个人开始喊,但count是同步的,这个第一个只是你个人的感觉,报数的规则并没有被破坏.....
我不认为算法有问题,如果有意见,你得拿出足够的理由说服我!
只要我们的array的size大于1,循环就不会结束。
sniperhuangwei
2007-09-14
打赏
举报
回复
java编程当真不需要考虑效率吗?
对这种简单的问题也动用封装好的库.
字符的连接操作导致了多少字符的移位,被拷贝,有没有考虑过.
Lisliefor
2007-09-14
打赏
举报
回复
楼上 Good idea !!
比用List子集,String的剪切来得更方便!更快捷!!
capturesource
2007-09-14
打赏
举报
回复
改变了的变态算法.
编号是从0开始的,如果从1开始,返回值+1就好......
public class KillMan {
/**
* @param args
*/
public static void main(String[] args) {
int liveNum=new KillMan().liveNum(100,7);
System.out.println("此人原来是"+liveNum+"号");
}
/*
* @total 总人数
* @killNum 不幸运数字
* */
private int liveNum(int total,int killNum){
String temp="";
for(int i=0;i<total;i++){
temp+=""+(char)(i+30000);
}
String tt=temp;
while(temp.length()!=1){
int ss=(killNum-1)%temp.length();
temp=ss==0?temp.substring(1):temp.substring(ss+1)+temp.substring(0,ss);
}
return tt.indexOf(temp);
}
}
capturesource
2007-09-14
打赏
举报
回复
http://community.csdn.net/Expert/topic/5738/5738951.xml?temp=7.319278E-02
jige_hanhan
2007-09-14
打赏
举报
回复
这样才是对的:
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public int callNum(int a) {
return ++a;
}
}
//----------------------------------------------
import java.util.ArrayList;
public class GetOut {
ArrayList <Person> array; // 队列
public GetOut(int NUM) {
array = new ArrayList<Person>();
// 人类初始化,加入队列中
for(int i=0;i<NUM;i++)
array.add(new Person("a" + i));
}
public Person out() {
int count = 0; // 喊吧
while(array.size()>1) {
int beginNum=0;
for(int i=beginNum;i<array.size();i++) {
Person p =array.get(i);
count = p.callNum(count);
// 喊道7,出局 计数从新开始
if(count == 7) {
array.remove(i);
count = 0; // 计数归0
}
}
beginNum=array.size()/7+1;
}
// 唯一的幸存者
return array.get(0);
}
public static void main(String [] args) {
int NUM = 100;
GetOut go = new GetOut(NUM);
Person p = go.out();
System.out.println("My name is " + p.name + "!");
}
}
amazeur
2007-09-14
打赏
举报
回复
学习一下。
jige_hanhan
2007-09-14
打赏
举报
回复
public Person out() {
int count = 0; // 喊吧
while(array.size()>1) {
for(int i=0;i<array.size();i++) {
Person p = (Person)array.get(i);
count = p.callNum(count);
// 喊道7,出局 计数从新开始
if(count == 7) {
array.remove(i);
count = 0; // 计数归0
}
}
这个不对,for结束时不一定是刚好喊到7,并且每次while判断后,都是第一个人从1喊,不符合lz要求的
sniperhuangwei
2007-09-14
打赏
举报
回复
更简单的方法看具体数学第一章,有公式可求.
加载更多回复(6)
【计算机网络常见面试题】IP地址
一道
计算题
已知172.31.128.255/18,试计算: 1、子网数目, 2、网络号, 3、主机号, 4、广播地址, 5、可分配IP的起止范围 1、算子网数目 首先将/18换成为我们习惯的表示法: 11111111.11111111.11000000.00000000转为十进制就是255.255.192.0,可以看到这个掩码的左边两节和B类默认 掩码是一致的,所以这个掩码是在B类
计算机网络中地址数怎么算,【计算机网络常见面试题】IP地址
一道
计算题
已知172.31.128.255/18,试计算:1、子网数目,2、网络号,3、主机号,4、广播地址,5、可分配IP的起止范围1、算子网数目首先将/18换成为我们习惯的表示法:11111111.11111111.11000000.00000000转为十进制就是255.255.192.0,可以看到这个掩码的左边两节和B类默认掩码是一致的,所以这个掩码是在B类默认掩码的范围内,意味着我们将对B类大网进行...
ctf解题--算术题
题目
一道
小学算术题,但是好多老师不会,不知道为什么 解题链接: http://ctf5.shiyanbar.com/program/2/ 解题 思路 5条连线的数字之和要相等,即把每条连线上的数字相加,相加的和(记作sum0)要能被5整除。 从上面的分析可以知道,填入的数字必须为1~10,也就是说内圈的数字要被重复计算一次,即(sum0 = 1+2+3+…+10+五个内圈的数字...
一道
cpu
计算题
一道
CPU
计算题
让计算机出
一道
形如A+B的四则运算题由用户输入结果若输入正确则输出《GOOD》若输入错误输出《SORRY》;
让计算机出
一道
形如A+B的四则运算题由用户输入结果若输入正确则输出《GOOD》若输入错误输出《SORRY》;
Java SE
62,614
社区成员
307,319
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章