c語言編寫n個人圍成一圈,按3報數,報到3的人退出

2021-03-07 07:51:10 字數 5809 閱讀 5888

1樓:匿名使用者

此題可用數學方法求解。

設有n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人繼續從0開始報數    (用數學方法解的時候需要注意應當從0開始編號,因為取餘會取到0解。)

實質是一個遞推,n個人中最終留下來的序號與n-1個人中留下來的人的序號有一個遞推關係式。

假設除去第k個人,則

0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1          // 原始序列 (1)

0, 1, 2, 3, ..., k-2,      , k, ..., n-1        // 除去第k人,即除去序號為k-1的人   (2)

k, k+1, ..., n-1,    0,    1,        ..., k-2  // 以序號k為起始,從k開始報0  (3)

0, 1,     ..., n-k-1, n-k, n-k+1, ..., n-2   // 作編號轉換,此時佇列為n-1人  (4)

變換後就完完全全成為了(n-1)個人報數的子問題,注意(1)式和(4)式,是同一個問題,不同的僅僅是人數。比較(4)和(3),不難看出,0+k=k, 1+k=k+1, ... ,(3)式中'0'後面的數字,

((n-3)+k)%n=k-3,((n-2)+k)%n=k-2, 對於(3)式中'0'前面的數字,由於比n小,也可看作(0+k)%n=k,  (1+k)%n=k+1,  故可得出規律:

設(3)中某一數為x' , (4)中對應的數為x,則有:x'=(x+k)%n.

設x為最終留下的人序號時,佇列只剩下1人時,顯然x=0; 此時可向前回溯至2人時x對應的序號,3人時x對應的序號……直至n人時x的序號,即為所求。

#include

const int m = 3;

int main()

2樓:手機使用者

以前做過的,貼一個給你,人數和報的數都可以輸入的 #include#include//應用函式呼叫來實現

void fun_kill(int *pa,int n,int m)i=0;int mcount=0;

int icount=0;

while(icount人數小於總人數if(mcount==m)i++;//報數的同時指標也開始走動if(i==n)}for(i=0;i

scanf("%d",&n);

printf("請輸入要報的數:");

scanf("%d",&m);

int *pkill=(int *)malloc(sizeof(int)*n);

fun_kill(pkill,n,m);

是c語言,有n個人圍成一圈,順序排號,從第一個人開始報數,從1到3,凡報到3的人退出圈子,問最後留 20

3樓:四四十六

n=1,1留,n=2,2留,n=3,2留,n=4,1留,5,4留。然後n大於等於6時,n=6,1留,n=7,4留,n=8,7留,…即留=3乘以(n除以3的餘數)+1。n>=6

4樓:匿名使用者

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

#include "windows.h"

void printpre(int* player,int len,int pos)

printpre(player,lenth,pos);

printf("%d",player[pos]);

return 0;}

5樓:漠影歌

需要用到遞迴,方法的話每次迴圈的時候遇到3的時候就跳出這個迴圈,把剩下的數存入一個陣列,遞迴這個陣列,繼續遇到3的迴圈,再遞迴陣列,再迴圈,一直到只有1一個數為止

6樓:功悵水戟

第一次報1和2的留下

c語言:有n個人圍成一圈,從第一個人開始報數1、2、3,每報到3的人退出圈子。程式設計使用【連結串列】找出 70

7樓:匿名使用者

#include

#include

using namespace std;

struct node

;int main()

else

cout<<"請輸入第 "<>(p->code);

p->no=i;

}p->next=first; //讓表尾指向表頭形成迴圈連結串列p=first;

cout<<"出列順序為: ";

for (j=1;j<=n;j++)

cout<

return 0;}

c語言程式設計:有n個人圍成一圈,按順序從1到n編號。從第一個人開始,報到3的人退出圈子。

8樓:凌亂心扉

#include

int main(int argc,char*argv);printf("請輸入有幾個人玩遊戲:");

scanf("%d",&n);

for(i=0;i

for(i=1;i<4;i=i%3+1)//控制i的值在[0,3]if(0==a[j])

j=(j+1)%n;

}for(i=0;i}

9樓:滄海雄風

#include

struct serial

;void main()

q->next =p->next ;

printf("被刪除的元素:%-4d\n",p->num);

p=q->next ;

}printf("\n最後報號出來的是原來的:%d\n",p->num);}8

被刪除的元素:3

被刪除的元素:6

被刪除的元素:1

被刪除的元素:5

被刪除的元素:2

被刪除的元素:8

被刪除的元素:4

最後報號出來的是原來的:7

press any key to continue

10樓:匿名使用者

此題可用數學方法求解。

設有n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人繼續從0開始報數  (用數學方法解的時候需要注意應當從0開始編號,因為取餘會取到0解。)

實質是一個遞推,n個人中最終留下來的序號與n-1個人中留下來的人的序號有一個遞推關係式。

假設除去第k個人,則

0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1          // 原始序列 (1)

0, 1, 2, 3, ..., k-2,      , k, ..., n-1        // 除去第k人,即除去序號為k-1的人   (2)

k, k+1, ..., n-1,    0,    1,        ..., k-2  // 以序號k為起始,從k開始報0  (3)

0, 1,     ..., n-k-1, n-k, n-k+1, ..., n-2   // 作編號轉換,此時佇列為n-1人  (4)

變換後就完完全全成為了(n-1)個人報數的子問題,注意(1)式和(4)式,是同一個問題,不同的僅僅是人數。比較(4)和(3),不難看出,0+k=k, 1+k=k+1, ... ,(3)式中'0'後面的數字,((n-3)+k)%n=k-3,((n-2)+k)%n=k-2,

對於(3)式中'0'前面的數字,由於比n小,也可看作(0+k)%n=k,  (1+k)%n=k+1,  故可得出規律:

設(3)中某一數為x' , (4)中對應的數為x,則有:x'=(x+k)%n.

設x為最終留下的人序號時,佇列只剩下1人時,顯然x=0; 此時可向前回溯至2人時x對應的序號,3人時x對應的序號……直至n人時x的序號,即為所求。

#include

const int m = 3;

int main()

return 0;}

11樓:餘啊水中游啊遊

這是約瑟夫環問題。

#include

#define m 43/*總人數*/

#define n 3

#define start 0/*第一個報數的人*/void main(void)

getch();}

12樓:小翼

經典約瑟夫環問題:

// n個人(1..n)圍成一圈,從m開始報數,增量為k// 返回最後一個人的編號,o(n)複雜度;

int josephus(int n,int k,int m)

13樓:匿名使用者

請問這個n有取值範圍嗎?

目前我有兩種思路,一種簡單的方式是用長度為n的陣列記錄,初始化為1,當計數到3是把對應的陣列下標輸出,並賦值為0.依次重複直到只剩下一個1.

第二種還是我的初步構想,找出退出的規律,可能可以用遞迴到n=1的情況。

14樓:華慧

我也不知道 等別人回答吧

c語言:有n個人圍成一圈,順序排號。從第一個人開始報數(從1~3報數),報到3的人退出圈子,求退出順序

15樓:匿名使用者

講一下基本思路,

定義一個陣列,先全部歸零。

然後處理,當零的時候沒有退出,1的時候推出知道推出到最後一個核心**

int a[1000], n, i, num=1, index=0,flag=1;

scanf("%d", &n);

memset(a, 0, sizeof(a));

while(num!=n+1)

else flag++;

}index++;index%=n;

}for(int i=1;i<=n;i++)printf("\n")

16樓:匿名使用者

#define n 100; //這裡你隨便改。

int result[n]; //這個陣列用來存放結果,為了一一對應,n個人裡,第一個的序號是0,不是我們習慣採用的1。

int flag[n]; //這個陣列用來標記這個n個人的狀態,一一對應,報過3的所對應的標記為1,否則0。

所以初始化話時,flag裡面都為0。

for(int i = 0; i < n; i++) flag[i] = 0;

當陣列flag裡面所有的元素都為1的時候,也就是flag的和為n時,表示計算完成了。

為了使調理清晰先做一個子函式bool sumflag()

bool sumflag()

下面開始運算

int currentnumber = 1; //這個變數用於記錄報數值。

int index = 0; //這個變數用於記錄寫入result的索引號。其實也可以用這個值來判斷是否完成了計算。

while(sumflag()) //當flag裡面不全是1的時候,進行下面的操作,否則結束。

else currentnumber++; //當前報數不是3,則要麼是1,要麼是2,直接增加報數值。}}

17樓:匿名使用者

不能除錯,不知道對不對,不過想來沒有問題,你試試#include"iostream.h"

void main()

num++;

mk=0;

}mk++;

}for(i=0;i

18樓:匿名使用者

#include

int main()

else

count++;}}}

n個人圍成一圈,1 3報數,報到3的退出圈外,如此迴圈,最後哪個人留下?(用指標解決)

你這裡有明顯的死迴圈。你把i地址給了select 但是你在select 當中從來就沒有改變過i的值,那就是說無論執行多少次,你的i始終都是20,那你就一直在while 裡面轉了啊。用c寫了個例子 你跑跑看效果 include main if array i 0 for i 0 i c語言編寫n個人圍...

用C語言如何編寫1 1 41 n

給你復個用遞迴方法的,這種題目制一bai般是用遞迴演算法做的 include include long double fun int n main long double fun int n else 思路復 奇數制 項是加,偶數項是減。int funtion int n c語言用函式編寫 1 1 ...

求編寫C語言程式,求編寫一個C語言程式

include stdafx.h vc 6.0加上這一行.include stdio.h void main void i int tmp printf 請輸入前17位號碼 scanf s a for tmp i 0 i 17 i tmp a i 0 b i tmp 11 tmp 12 tmp 11...