簡單的約瑟夫問題:使用陣列,模擬乙個圈,每次數到m就標記為已讀,並將num還原為0
接著從下乙個人開始,如果到了最後乙個人,就重新回到第乙個人,繼續開始尋找,如果沒有被標記過num(數到的數字)++,直到所有人都退出圈子結束
源**
1 #include 2 #include 3 #include 4using
namespace
std;
5int
main()625
if (ans==n)
26break;27
}28return0;
29 }
已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。
例如:n = 9, k = 1, m = 5
【解答】
出局人的順序為5, 1, 7, 4, 3, 6, 9, 2, 8。
第一種變法,從第k個人開始數,即把迴圈的初始值設為k即可
1 #include 2 #include 3 #include 4using
namespace
std;
5int
main()625
if (ans==n)
26break;27
}28return0;
29 }
編號為1,2,....,n的n個人按順時針方向圍坐一圈,每人持有乙個密碼(正整數).一開始任選乙個正整數作為報數上限值m,從第乙個人開始按順時針方向自1開始順序報數,報到m時停止報數.報m的人出列,將他的密碼作為新的m值,從他在順時針方向上的下乙個人開始 重新從1報數,如此下去,直至所有人全部出列為止.試設計乙個程式求出出列順序.
測試資料:
n=7;7個人 的密碼依次為:3,1,7,2,4,8,4,首先m值為6(正確的出列順序應為6,1,4,7,2,3,5)
變式2:仍從第乙個人開始數,只是每一次m都要重新更新,我們就在每次數到當前m的同時,將m更新
1 #include 2 #include 3 #include 4using
namespace
std;
5int
main()629
if (ans==n)
30break;31
}32return0;
33 }
n個人排成一圈。從某個人開始,按順時針方向依次編號。從編號為1的人開始順時針「一二一」報數,報到2的人退出圈子。這樣不斷迴圈下去,圈子裡的人將不斷減少。由於人的個數是有限的,因此最終會剩下乙個人。試問最後剩下的人最開始的編號。
輸入格式 input format
乙個正整數n,表示人的個數。輸入資料保證數字n不超過100。
輸出格式 output format
乙個正整數。它表示經過「一二一」報數後最後剩下的人的編號。
樣例輸入 sample input :9
樣例輸出 sample output:3
變式3:
怎麼說呢,寫的很複雜,首先它是1 2 1 2 1 2 1 2 報數的,題目描述的比較模糊。
先定義乙個dir陣列為1 2兩個數字
兩層迴圈,乙個人對應乙個數,如果這個人恰好在圈中而且報數為2,那麼我們就可以把他踢出去
1int dir[3]=;
2for (int i = 1;i <=n;)318
19if (vis[i]==1)20
28if (i==n)
29 i=1;30
else
31 i++;
32if (j==1
)33 j=0;34
else
35 j++;
因為是乙個環,所以我們可以清楚的了解到,每次如果i=n,我們就要重新從第乙個人開始
如果這個人已經被訪問過,我們就直接計算他的下乙個人,但是應該報的數不變
完整**....好長
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;
6int
main()7;
14for (int i = 1;i <=n;)
1530
31if (vis[i]==1)32
40if (i==n)
41 i=1;42
else
43 i++;
44if (j==1
)45 j=0;46
else
47 j++;
48if (num==n-1
)
4955
return0;
56}57}
58}5960
return0;
61 }
圍繞著山頂有10個洞,狐狸要吃兔子。
兔子說:「可以,但必須找到我,我就藏身於這十個洞中,你從10號洞出發,先到1號洞找,第二次隔1個 洞找,第三次隔2個洞找,以後如此類推,次數不限。」
但狐狸從早到晚進 進出出了1000次,仍沒有找到兔子。問兔子究竟藏在哪個洞裡?
1 #include2 #include3 #include4 #include5using
namespace
std;
6int b[10000+5];7
intmain()820
else
2128
else
2933}34
}35for(int i=1; i<=10; i++)
3642}43
return0;
44 }
例如n=6,m=5,被殺掉的人的序號為5,4,6,2,3。最後剩下1號。
假定在圈子裡前k個為好人,後k個為壞人,你的任務是確定這樣的最少m,使得所有的壞人在第乙個好人之前被殺掉。
約瑟夫環變形 先引入joseph遞推公式,設有n個人(0,…,n-1),數m,則第i輪出局的人為
f(i)=(f(i-1)+m-1)%(n-i+1);
f(0)=0;
f(i) 表示當前子串行中要退出的那個人(當前序列編號為0~(n-i));
拿個例子說:k=4,m=30;
f(0)=0;
f(1)=(f(0)+30-1)%8=5; 序列(0,1,2,3,4,5,6,7)中的5
f(2)=(f(1)+30-1)%7=6; 序列(0,1,2,3,4,6,7)中的7
f(3)=(f(2)+30-1)%6=5; 序列(0,1,2,3,4,6)中的6
f(4)=(f(3)+30-1)%5=4; 序列(0,1,2,3,4)中的4
……..
依據題意,前k個退出的人必定是後k個人,所以只要前k輪中只要有一次f(i)小於k則此m不符合題意。
<--原**
1 #include 2 #include 3 #include 4using
namespace
std;
5 typedef long
long
ll;6
const
int inf=int_max;
7const
int maxn = 110;8
int k,ans[20],joseph[20];9
void
init()
1022}23
if(ok) break
;24 m++;25}
26 joseph[k]=m;27}
28}29int
main()
3035
return0;
36 }
UVA 1452 Jump 約瑟夫環變式
題目大意 給出n,m,約瑟夫環共n項,每數到m殺乙個人,問剩下的倒數第3個人 倒數第2個人 倒數第1個人的編號分別是多少 題解 因為我們都知道求約瑟夫環問題是f 1 0,f n f n 1 k i 所以一開始我的想法是就用同樣的方法來推倒數第2個人,f 2 0,f n f n 1 k i 但是得出的...
約瑟夫問題兩種實現方式
陣列版本 include include main int p int malloc len sizeof int printf 請輸入步長 n scanf d pace if pace 0 if pace 0 printf 請輸入進行輪數 n scanf d time printf 請輸入您想從那...
約瑟夫問題兩種實現方式
陣列版本 include include main int p int malloc len sizeof int printf 請輸入步長 n scanf d pace if pace 0 if pace 0 printf 請輸入進行輪數 n scanf d time printf 請輸入您想從那...