题目描述:
有n个小朋友做游戏,他们的编号分别是1,2,3…n。他们按照编号从小到大依次顺时针围成一个圆圈,第一个小朋友从1开始报数,依次按照顺时针方向报数(报数的值加一),每个报m的人会离开队伍,然后下一个小朋友会继续从1开始报数,直到只剩下一个小朋友为止。
求最后一位小朋友的编号。
Input
输入两个数字n,m(1<=m<=n<100000),用空格隔开。
Output
输出最后一个小朋友的编号,独占一行。
Sample Input 1
7 5
Sample Output 1
6
仔细分析,用数组,循环解决:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include<stdio.h> #include<stdlib.h> int main() { int n,k,i; scanf("%d%d", &n, &k); int *arr=(int*)calloc(n,sizeof(int)); for(i=0;i<n;i++){ arr[i]=i+1; } int t=0,num=n; for(i=1; ;i++){ if(i>n) i=1; if(arr[i-1]!=0) ++t; if(t==k){ arr[i-1]=0; --num; t=0; } if(num==1) break; } for(i=0;i<n;i++){ if(arr[i]!=0){ printf("%d",arr[i]); break; } } return 0; }
|
百度借鉴大佬的代码,不用数组,用链表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include<stdio.h> #include<stdlib.h> typedef struct List { int data; struct List *next; }list; int main() { list *L = (list*)calloc(1, sizeof(list)); L->next = NULL; int n, k, i; scanf("%d%d", &n, &k); list *s, *q = L; for (i=0; i<n; ++i) { s = (list*)calloc(1, sizeof(list)); s->data = i+1; s->next = NULL; q->next = s; q = s; } q->next = L->next; q = L->next; while (q->next != q) { for (i=1; i<k-1; ++i) {q = q->next;} s = q->next; q->next = s->next; q = q->next; free(s); s = NULL; } printf ("%d\n", q->data); free(q); q = NULL; free(L); L = NULL; return 0; }
|
后来还有大佬写出迄今为止看到的最短小版本 tql:
1 2 3 4 5 6 7 8 9 10
| #include<stdio.h> int main(){ int n, k, i, s = 0; scanf("%d%d", &n, &k); for (i = 2; i <= n; ++i){ s = (s+k)%i; } printf("%d\n", s+1); return 0; }
|