Bailian2746 約瑟夫問題
阿新 • • 發佈:2019-01-01
2746:約瑟夫問題
總時間限制: 1000ms 記憶體限制: 65536kB
描述
約瑟夫問題:有n只猴子,按順時針方向圍成一圈選大王(編號從1到n),從第1號開始報數,一直數到m,數到m的猴子退出圈外,剩下的猴子再接著從1開始報數。就這樣,直到圈內只剩下一隻猴子時,這個猴子就是猴王,程式設計求輸入n,m後,輸出最後猴王的編號。
輸入
每行是用空格分開的兩個整數,第一個是 n, 第二個是 m ( 0 < m,n <=300)。最後一行是:
0 0
輸出
對於每行輸入資料(最後一行除外),輸出資料也是一行,即最後猴王的編號
樣例輸入
6 2
12 4
8 3
0 0
樣例輸出
5
1
7
問題連結
問題簡述:(略)
問題分析:
約瑟夫問題有2種解法,一是模擬法,二是數學法。
數學法需要數學推導,這裡略去推導過程,只給出程式。
模擬法可以使用多種資料表示,例如資料結構和STL,這裡給出用陣列進行模擬的方法。由於邏輯簡單,時間上應該更快一些。
程式說明:(略)
參考連結:(略)
題記:(略)
AC的C語言程式(模擬法)如下:
/* Bailian2746 約瑟夫問題 */ #include <stdio.h> #define N 300 int a[N]; int main(void) { int n, k, m, pos, cnt; while(scanf("%d%d", &n, &m) != EOF && (n || m)) { for( k = 0 ; k < n ; k++ ) a[k] = k+1; for( k = 1, pos = 0; k < n; k++) { cnt = 0; while( cnt < m ) { while( a[pos] == 0 ) pos++, pos %= n; if(++cnt < m) pos++, pos %= n; } a[pos] = 0; pos++, pos %= n; } /* 輸出結果 */ for(k = 0; k < n; k++) if(a[k]) { printf("%d\n", a[k]); break; } } return 0; }
AC的C語言程式(數學法)如下:
/* Bailian2746 約瑟夫問題 */ #include <stdio.h> int main(void) { int n, m, i, s=0; while(scanf("%d%d", &n, &m) != EOF && (n || m)) { s=0; for (i = 2; i <= n; i++) s = (s + m) % i; printf ("%d\n", s + 1); } return 0; }