参考方法:
#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; }
为了尽量减少不必要的循环,做了如下的小优化。
#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); } } } }
先确定哪个位置的人会报出 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++; //报数自加 } }
用一种比较复杂的方式解决。
前面的用的方法都比较简单,可惜我没想到,我一上来就想的是用循环链表。
#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; }
#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; }
感谢您的支持,我会继续努力的!
支付宝扫一扫,即可进行扫码打赏哦
1630c-exercise-example1
参考方法:
1629c-exercise-example1
为了尽量减少不必要的循环,做了如下的小优化。
1628c-examples-joseph-life-dead-game
先确定哪个位置的人会报出 9,找到之后下一次跳过此人,直至人数等于 15。
1627c-examples-joseph-life-dead-game
用一种比较复杂的方式解决。
前面的用的方法都比较简单,可惜我没想到,我一上来就想的是用循环链表。
1626c-examples-joseph-life-dead-game