今天老師布置了個題目,約瑟夫環,俗稱猴子選大王。n個人報數,報到3的退出,最后留在場上的時原來的第幾位
#include <stdio.h>int main()
{int i, n, q, p = 0; //計數 i ,人數 n ,報數 p ,場上人數 qprintf ("input number");scanf ("%d", &n);q = n;int a[n];for (i = 0; i < n; i++) //將1到n輸入進數組a{ a[i] = i+1;}for (i = 0; ; i++){if (i == n) /*當i++一直到n時,肯定有一些沒被選到,比如我們輸入8,第一輪是3,6被賦值0,當i=8時,繼續下一輪*/{i = 0;}if (0 != a[i]) /*我們下面定義的時當循環到三時,就賦值0,所以這邊等于0的不考慮在內*/{p++;}else continue;if (0 == p%3) //這個就是從0一直加,到三的倍數就賦值為0,從而達到我們的目的{a[i] = 0;q--; //上面q=n;標明q==n,只有一個為0就減一,為下面做鋪墊}if (1 == q) //當剩下最后一個就輸出{break;}}for (i = 0; i < n; i++) //輸出最后一個人的編號{if (0 != a[i])printf ("spare:%d\n", a[i]);}return 0;
}
后來在網上又看到2種不同的方法,一種是用的指針
#include <stdio.h>
int main()
{ int i, j, k, m, n; int *p; printf ("input number");scanf ("%d", &n); int num[50];p = num; for(i = 0; i < n; i++) { *(p+i) = i + 1; //以1至n為序,給每個人編號 } i = 0; //i為每次循環時計數變量 k = 0; //k為按1 2 3報數時的計數變量 m = 0; //m為退出人數 while(m < n-1) //當退出人數比n-1少時(即未退出人數大于1時)執行循環體 { if(0 != *(p+i)) { k++; } if(3 == k) //將退出人的編號置為0 { *(p+i) = 0; k = 0; m++; } i++; if(i == n) { i = 0;//報數到尾后i恢復為0 } } while(0 == *p) { p++; } printf ("最后一個是:%d\n", *p);return 0;
}
還有個牛人的,代碼很簡練(裝13)
#include <stdio.h>int main()
{ int n, i, s = 0;int M = 3; printf ("input number");scanf ("%d", &n); for (i = 2; i <= n; ++i) s = (s+M) % i; printf("%d\n", s+1); return 0;
}