hdu 1443 Joseph【約瑟夫環】
阿新 • • 發佈:2018-12-10
題意:一共有2k個人,分別為k個好人和k個壞人,現在我們需要每隔m個人把壞人挑出來,但是條件是最後一個壞人挑出來前不能有好人被挑出來。。問最小的m是多少
約瑟夫環問題,通常解決這類問題時我們把編號設為從0~n-1。
求出每一輪出列的人:start = (start + m - 1) % n
模擬過程如下(以六個人,第五為例):
1 2 3 4 5 6 易發現start1 = (0 + 5 - 1)% 6 = 4, 即a[4] = 5這個人出列
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int k,a[15]; bool IsGood(int k, int x){ int start = 0, n = k*2; while(n > k){ start = (start + x - 1) % n; if(start < k) return false;//要kill的這個人是否 < k else n--; } return true; } void init(){ for(int k=1; k<=13; k++) for(int hoop=1; ; hoop++) if(IsGood(k,hoop)) {a[k] = hoop; break;} } int main(){ init(); while(scanf("%d",&k) == 1){ if(k == 0) break; printf("%d\n",a[k]); } return 0; }
原始約瑟夫環問題程式碼:
/* 約瑟夫環問題 */
# include <stdio.h>
int main()
{
int m, n, i, s;
while (~scanf("%d%d", &m, &n))
{
s = 0;
for (i = 2; i <= n; ++i)
s = (s + m) % i;
printf("%d\n", s+1); // 原問題的編號是從1開始的
}
return 0;
}