C 语言教程 在线

1630c-exercise-example1

参考方法:

#include<stdio.h>
int main(void)
{
    int i,j,k;
    for(i = 1;i < 5;i++)
    {
        for(j = 1;j < 5;j++)
        {
            if(i == j)
                continue;
            for(k = 1;k < 5;k++)
            {
                if(i == k || j == k)
                    continue;
                printf("%d,%d,%d\n",i,j,k);
            }
        }
    }
    return 0;
}

1629c-exercise-example1

为了尽量减少不必要的循环,做了如下的小优化。

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint32_t i; // 百位
    uint32_t j; // 十位
    uint32_t k; // 个位
    
    for (i=1; i<5; i++)
    {
        for (j=1; j<5; j++)
        {
            // 百位与十位重复
            // 跳过当前十位
            if (j==i)
            {
                continue;
            }
            
            for (k=1; k<5; k++)
            {
                // 个位与百位或十位重复
                // 跳过当前个位
                if (k==j || k==i)
                {
                    continue;
                }
                
                printf("%u,%u,%u\n", i, j, k);
            }
        }
    }
}

1628c-examples-joseph-life-dead-game

先确定哪个位置的人会报出 9,找到之后下一次跳过此人,直至人数等于 15。

#include<stdio.h>

int main()

{
    int i= 1;   //绝对位置参数,代表当前的真实位置
    int size = 30;  //总人数
    int b = 1;  //当前的报数,或者说相对位置,每循环一次都加1,至多为9
    int flag[30];   //记录数组,记录当前位置是否已选,已选记为1
    for(int j = 0 ; j < 30 ; j++)
    {
         flag[j] = 0;   //记录数组初始化为0   
    }
    int num[30];    //位置数组
    for(int j = 0 ; j < 30 ; j++)
    {
        num[j] = j+1;   //位置数组初始化
    }

    while(size >15) //15人下船,因此人数大于15时才执行
    {
        if(i == 31) //30即为最后一个人,下一轮要从头开始,因此30的下一个31实际是第1
            i = 1;
         if(b == 10)    //以9为循环,报数到9,下一个10改报1
                b = 1;
          if(flag[i] == 1)  //判断之前是否已经报过9
            {
                    b--;  //跳过之前被选的人
                            //举例说明:第一轮筛选,9这个位置被选了,并通过flag[8]记录9这里已选。在第二轮筛选时就需要跳过9这里,假设第二轮第8个位置报数是1,第9个位置跳过,则第10个位置的报数为2。
                            //而每次循环b都自加,所以9这里b自减,保证位置10的b值正确,其他位置同理
            }  
            if(b == 9) //若当前报数为9
            {
                flag[i] = 1;    //标记此人已经报出过9
                printf("%d\n" , num[i-1]);    //打印报数为 9 的人的绝对位置
                size--;     //找到一个人,总人数减1
            }
            i++;    //绝对位置自加
            b++;    //报数自加
    }
}

1627c-examples-joseph-life-dead-game

用一种比较复杂的方式解决。

前面的用的方法都比较简单,可惜我没想到,我一上来就想的是用循环链表。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct num{
    int num;
    struct num * next;
}student ;
int main()
{
    int i,j;
    student* head = NULL;
    student* tail = NULL ;
    student* p = NULL;
    student* q = NULL;
    student *temp;
    bool ishead = true;

    for(i=1;i<31;i++)
    {
        student *people = malloc(sizeof(student));
        people->num=i;
        if(ishead){
            head = people;
            head ->next = NULL;
            tail = people;
            ishead = false;
        }
        else
        {
            tail->next = people;
            tail = people;
        }
    }
    if(NULL!=tail || NULL == tail)
        tail ->next = head;
    i=30;
    p=head;
    q=head;
while(i>15)    
{
    for(j=1;j<10;j++)
    {
        //printf(" now the num %d \n",p->num);
        if(j==9)
        {
            printf("the num %d get off \n",p->num);
                
            i--;
            q->next = p->next;
            free(p);
            p=q->next;
        }
        else{
            q=p;
        p=p->next;
        }
    }
}
   return 0;
}

1626c-examples-joseph-life-dead-game

#include <stdio.h>

int main()
{
    int arr[30];  //创建30的数组,值全部为1
    for(int i = 0;i<30;i++){
        arr[i]=1;
    }

    int nowP = -1;  //当前报出的数,-1 开始因为 while 一开始就要 ++
    int callTime = 0;  //当前共有几个人下船,即完成了几次0-8(1-9)的报数
    int realP = -1;    //当前报数的人的真是位置
    while(callTime!=15){   //只要下船人数没达到15 即一只报数
        realP++;           //开始记录当前哪个位置在报
        if(realP == 30)realP = 0;   //如果当前该坐标为30的人,即第"31"个人报,马上切换到第0个人开始报
        if(arr[realP] != 0)nowP++;  //如果当前人的状态不是0,即仍在船上,就记录一次报数。
        if(nowP == 8){    //如果报到的数字为8,即第九人,则下船人数+1
            callTime++;
            arr[realP] = 0;   //1改为0,标记为已下船
            nowP = -1;        //重置nowP,下一个人继续从0报
            printf("Number %d is out.\n",realP+1);  //输出当前下船的人
        }
    }
    return 0;
}