黑马程序员技术交流社区

标题: 耶稣有15个门徒的代码解析,不懂的可以问我,谢谢 [打印本页]

作者: chingwei2011    时间: 2015-10-10 18:33
标题: 耶稣有15个门徒的代码解析,不懂的可以问我,谢谢
本帖最后由 chingwei2011 于 2015-10-12 13:14 编辑

忘了贴题目,就是15个人围一个圈,轮流报数1,2,3.报到3的退出游戏,下一位又从1开始报,以此类推,最后留下来的那个是多少编号。
对于这道题算法很多,这个算法我想了很久,很笨,倒是能最直接的翻译这道题。
#include <stdio.h>
int main(int argc, const char * argv[]) {
    int last[15]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    static int count=1;// 一定要用静态修饰符 修饰,否则在flag==2的时候会出现死循环的问题。
    int flag = 15;//15个人需要判断14次
    while(flag > 1){
        for(int i = 0; i < 15; i++){
            if(count == 3 && last != 0){ //累计数3次的时候,从剩下的人中再排除一个
                last = 0;//将被排除掉的人赋值0,表示已排除
                count=1;//从新计算步数
                flag--;
                //printf("B [%d] ,flag=%d\n",i,flag);
            }
            else if(last != 0)
            {
                count++;
                //printf("A [%d], count=%d\n",i,count);
            }               
        }
    }
    for( int i =0 ;i < 15 ;i++)
        if(last!=0){
            printf("15人中第%d个是嫌疑人!\n",last);
        }

作者: 朱玉丁    时间: 2015-10-10 21:58
赞,顶一个
作者: CherryQueen    时间: 2015-10-10 22:45
著名的约瑟夫环的问题,楼主好棒,加油
作者: wxd123    时间: 2015-10-10 23:31
楼主从哪找的题啊?
作者: yufanyufan77    时间: 2015-10-11 15:30
帮顶!!!!!!!!!!!
作者: chingwei2011    时间: 2015-10-11 15:45
wxd123 发表于 2015-10-10 23:31
楼主从哪找的题啊?

自己想的。。。 这是出自黑马的测试基础题目
作者: chingwei2011    时间: 2015-10-11 15:48
yufanyufan77 发表于 2015-10-11 15:30
帮顶!!!!!!!!!!!

谢谢哥。。。
作者: chingwei2011    时间: 2015-10-11 15:49
CherryQueen 发表于 2015-10-10 22:45
著名的约瑟夫环的问题,楼主好棒,加油

一起加油呀,小兄弟。
作者: gabriel2016    时间: 2015-10-11 16:04
咦,有点眼shu,难道……是改的?
作者: chingwei2011    时间: 2015-10-12 00:10
gabriel2016 发表于 2015-10-11 16:04
咦,有点眼shu,难道……是改的?

自己写的哦。。连这样的都还要去抄袭,有什么值得贴出来的。
作者: gabriel2016    时间: 2015-10-12 01:29
“约瑟夫环”
作者: chingwei2011    时间: 2015-10-12 10:26
嗯嗯你说的是对的。这也是黑马的测试基础题的其中一道。。
作者: chingwei2011    时间: 2015-10-12 10:27
gabriel2016 发表于 2015-10-12 01:29
“约瑟夫环”

嗯嗯你说的是对的。这也是黑马的测试基础题的其中一道。。
作者: amoshaxiangp    时间: 2015-10-12 12:40
不错不错,我百度出来的算法对数学要求太高了。。瞬间感觉大学白上了。。。。
作者: 白马哥    时间: 2015-10-12 13:02
原来如此,小白学习了,谢谢啊!
作者: chingwei2011    时间: 2015-10-12 13:11
白马哥 发表于 2015-10-12 13:02
原来如此,小白学习了,谢谢啊!

谢谢白马哥指点,传递正能量!!
作者: snowimba    时间: 2015-10-12 16:44
用OC写了写下,10行不到搞定,一个while加一个for,看来OC真是方便多了
作者: chingwei2011    时间: 2015-10-12 20:26
snowimba 发表于 2015-10-12 16:44
用OC写了写下,10行不到搞定,一个while加一个for,看来OC真是方便多了

小哥。。。你贴下代码 我想看看,学习下。。。非常感谢。
作者: snowimba    时间: 2015-10-12 20:39
chingwei2011 发表于 2015-10-12 20:26
小哥。。。你贴下代码 我想看看,学习下。。。非常感谢。

  1. 注释是刚才现场看代码写的,将就看吧
复制代码
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
//        创建一个可变数组
            NSMutableArray *arr =[NSMutableArray array];
//        循环给可变数组赋值1-15
                    for (int i=0; i<15; i++) {

                [arr addObject:@(i+1)];

    }
//        定义一个计数器
        int count=0;

//        定义循环,直到数组只剩下一个元素停止
        while (((int)arr.count)>1) {
//            循环遍历数组
            for (int i=0; i<arr.count; i++) {
//                每循环一个元素,计数器就加一
                count++;
//                判断计数器是否为3
                if (count==3) {
//                    数组对应的元素变成“-”
                    arr=@"-";
//                    计数器归零
                    count=0;
                }
            }
//            将数组中所有“-”删除,然后再次循环
            [arr removeObject:@"-"];

        }

//        打印数组
        NSLog(@"%@",arr);
    }
    return 0;
}

作者: chingwei2011    时间: 2015-10-12 20:45
snowimba 发表于 2015-10-12 20:39
#import
int main(int argc, const char * argv[]) {    @autoreleasepool {//        创建一个可变数组 ...

感觉思路挺像的,OC的语法确实简练。厉害,学习了、
作者: 黑马公公007    时间: 2015-10-13 08:57
能不能悄悄的告诉你,我在做入学测试的时候写过这道题
作者: Brisingr    时间: 2015-10-13 10:34
好厉害的样子

作者: 408205555    时间: 2015-10-13 11:47
楼主,你代码不仅书写错误,而且逻辑也错误。

1、while是死循环,()里直接写1就行了
2、while是死循环,没有跳出循环的条件会一直死循环。
3、while死循环里放一个for循环,完全不懂什么意思,而且运行也没结果,说明逻辑错了。
4、约瑟夫环,只是一个环,只在一个环里转,要有合适的判断条件和跳出机制。
作者: 408205555    时间: 2015-10-13 11:52
snowimba 发表于 2015-10-12 20:39
#import
int main(int argc, const char * argv[]) {    @autoreleasepool {//        创建一个可变数组 ...

你的代码也是错的。
作者: wuchuanyuan    时间: 2015-10-13 12:31
写的这么简单额,你还需要像白马哥学习啊,我在龙之港,可以一起探讨。。
作者: jy00889669    时间: 2015-10-13 12:55
学习学习
作者: snowimba    时间: 2015-10-13 15:08
本帖最后由 snowimba 于 2015-10-13 15:09 编辑
408205555 发表于 2015-10-13 11:52
你的代码也是错的。

复制粘贴的时候系统把arr后面漏了【i】,这个是系统默认屏蔽的,我前面看到了,懒得改了,毕竟懂代码的都明白,自己可以加上。其他的地方还有什么错误请指出来,我敢发上来肯定是运行过的,没有错误,而且得出结果的。我的是那个OC代码,你既然说错了,应该有理由的,还望指出。
作者: chingwei2011    时间: 2015-10-13 20:05
黑马公公007 发表于 2015-10-13 08:57
能不能悄悄的告诉你,我在做入学测试的时候写过这道题

喔谢谢,你已经进到黑马了吗。
作者: chingwei2011    时间: 2015-10-13 20:07
408205555 发表于 2015-10-13 11:47
楼主,你代码不仅书写错误,而且逻辑也错误。

1、while是死循环,()里直接写1就行了

1.有跳出循环的条件,就是判断到14次的时候 ,就会跳出,即flag==1的时候 跳出
感谢你的点评。我下次会仔细些。非常感谢你的指导
作者: 408205555    时间: 2015-10-13 21:21
chingwei2011 发表于 2015-10-13 20:07
1.有跳出循环的条件,就是判断到14次的时候 ,就会跳出,即flag==1的时候 跳出
感谢你的点评。我下次会 ...

我运行你的代码了,是死循环。

其实一个while循环就可以搞定。

里面的for循环显得有些多余。

可以通过定义一个数组索引 i 来进行判断和取数组中的值。
作者: 黑马公公007    时间: 2015-10-14 08:17
chingwei2011 发表于 2015-10-13 20:05
喔谢谢,你已经进到黑马了吗。

你看我等级跟技术分,没呐!
作者: chingwei2011    时间: 2015-10-14 11:39
黑马公公007 发表于 2015-10-14 08:17
你看我等级跟技术分,没呐!

嗯嗯是要报下个月11号的吗。。
作者: chingwei2011    时间: 2015-10-14 11:40
408205555 发表于 2015-10-13 21:21
我运行你的代码了,是死循环。

其实一个while循环就可以搞定。

晕死。我运行结果是正常的,vc++和xcode环境都运行 显示结果是 5.好我再试试。谢谢
作者: Abuzzworld    时间: 2015-10-14 11:44
  1. #include <stdio.h>

  2. int main(int argc, const char * argv[]) {
  3.    
  4.     //定义一个数组并全部初始化为0
  5.     int p[15]={0};
  6.     //i用来标记该元素是否应该退出,j用来无限循环数组元素,k标记剩余人数
  7.     int i=1,j=15,k=15;
  8.     //只要剩余人数大于1,就一直进行循环
  9.     while(k>1){
  10.         //数组元素值为0,代表尚未出局,可参与循环,值为1,则表示已经出局,不参与循环
  11.         //如果数组中该元素的值为0,并且该元素没有被标记为3,则标记i++
  12.         if(p[j%15]==0&&i!=3){
  13.             i++;
  14.             
  15.             //如果数组中某元素值为0,且被标记为3,则将该元素值改为1,表示该元素出局,同时标记计数器重置为1,剩余人数-1
  16.         }else if(p[j%15]==0&&i==3){
  17.             p[j%15]=1;
  18.             i=1;
  19.             k--;
  20.         }
  21.         //不管结果如何,j都会进行自加运算,以保证下一元素进入循环
  22.         j++;
  23.     }
  24.     //当剩余人数为1的时候,while结束,用找出为0的人,就是叛徒,它的序号就是该元素的下标+1
  25.     for(i=0;i<15;i++){
  26.         if(p[i]==0){
  27.             printf("出卖耶稣的序号是:%d\n",i+1);
  28.         }
  29.     }
  30.     return 0;
  31. }
复制代码

作者: wqp123000    时间: 2015-10-14 11:49
谢谢大哥,我基础测试也是这个,没有写出来
作者: 黑白世界    时间: 2015-10-14 14:10
好厉害啊
作者: ff774411    时间: 2015-10-14 16:46
学习了,OC作为C的拓展,还真是简单了许多
作者: 黑马公公007    时间: 2015-10-15 08:17
chingwei2011 发表于 2015-10-14 11:39
嗯嗯是要报下个月11号的吗。。

是的是的
作者: chingwei2011    时间: 2015-10-15 10:50
Abuzzworld 发表于 2015-10-14 11:44

谢谢大哥。。。学习了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2