c語言n個人圍成一圈
『壹』 c語言 有n個人圍成一圈,按順序從1到n編號。從第一個人開始報數,報數3的人退出圈子
#include <stdio.h>
#define N 9999
int main()
{
int n,a[N],*p,i=0,out=0,count=0;
printf("Input n(n must be a natural number less than 10000):");
scanf("%d",&n);
if(n>=10000)
printf("n is out of range of valid values.");改為printf("%d is out of range of valid values.",n);
else
{
for(i=0;i<=n;i++) 改為a[i]=i;
a[i+1]=i; //這樣做a[0]是個不確定的值,執行完p=a;後*p
p=a; 的值也是不確定的,後面的if判斷條件不確定了
while(out!=n){ 這兒應該是out!=n-1吧
if(*p!=0) 這段可以改成這樣for(;;){ if(*p!=0){
count++; count++;p++;}結束if
if(count==3){ if(count==3){ out++; out++;
*p=0; *p=0; break;}結束if
} }結束for
count=0; //此處導致count永遠只能是0或1所以out的值不會變
把這兒的p++刪了 p++; while就成死循環了
if(*p==a[n-1]) 把這個if語句嵌套到if(*p!=0)里的p++後面這兒不要了
p=a;
}
printf("%d",*p);
}
return 0;
}
這樣改完後應該能把最後剩下的號碼打出,其實可以把出局的順序也打出來樓主想想啊,挺簡單的,而且好像有很短的代碼解決這個問題,多思考啊
『貳』 C語言:有n個人圍成一圈,順序排號。從第一個人開始報數(從1到3報 數),凡報到3的人退出圈子....
目測沒有問題。結果顯示最後剩下的那個數字。
邏輯為:
1、給數據賦值
for(i=0;i<n;i++)/*數組a存放原始編號*/
a[i]=i+1;
2、將報到3的人退出圈子,因為最後只剩下一人,所以條件是quit_num<n-1=99
while(quit_num<n-1)/*直到只剩下1人時*/
{if(a[i]!=0)k++; /*報數,等於0的已經退出圈子*/
if(k==3) /*報數為3*/
{a[i]=0; /*退出圈子*/
quit_num++; /*統計人數*/
k=0; /*下次報數重新從一開始*/
}
i++; /*下次循環判斷數組的下一個*/
if(i==n)i=0; /*循環到數組的最後一個,下次循環指定到第一個*/
}
3、輸出最後個數字
for(i=0;i<n;i++)
if(a[i]!=0)printf("%d",a[i]);
『叄』 C語言:有n個人圍成一圈,按順序從1到n編號。從第一個人開始報數。
#include<stdio.h>
int main()
{
int i,n,N,out,a[1000];
out=i=n=0;
printf("輸入約瑟夫圈大小 100 ");
scanf("%d",&N);
for(i=0;i<N;i++)
{
a[i]=1;
}
i=0;
while(out!=N-1)
{
if(a[i]==1)n++;
if(n==3){a[i]=0;n=0;out++;}
i++;
if(i==N)i=0;
}
for(i=0;i<N;i++)
if(a[i]==1)printf("最後剩下的是第%d個人",i+1);break;
return 0;
}
(3)c語言n個人圍成一圈擴展閱讀:
需要說明的是:
1、一個C語言源程序可以由一個或多個源文件組成。
2、每個源文件可由一個或多個函數組成。
3、一個源程序不論由多少個文件組成,都有一個且只能有一個main函數,即主函數。是整個程序的入口。
4、源程序中可以有預處理命令(包括include 命令,ifdef、ifndef命令、define命令),預處理命令通常應放在源文件或源程序的最前面。
5、每一個說明,每一個語句都必須以分號結尾。但預處理命令,函數頭和花括弧「}」之後不能加分號。結構體、聯合體、枚舉型的聲明的「}」後要加「 ;」。
6、標識符,關鍵字之間必須至少加一個空格以示間隔。若已有明顯的間隔符,也可不再加空格來間隔。
網路-c語言
『肆』 C語言:有n人圍成一圈,順序排號。從第1個人開始報數(從1到3報數),凡報到3的人退出圈子,
法一(模擬法):
#include<iostream>
usingstd::cin;
usingstd::cout;
intmain()
{
intn;
cout<<"請輸入n=";
cin>>n;
if(n<2)
{
cout<<"n必須大於2! 請重新輸入n=";
cin>>n;
}
bool*a=newbool[n+1];
a[0]=false;
for(inti=1;i<n+1;i++)
a[i]=true;
intx,k=n;x=i=0;//i為每次循環計數變數,x為人員序號,K為剩餘人數
while(k!=0)
{
x++;
if(x>n)x=1;//當人員到達數組尾,序號重設為1
if(a[x])i++;//跳過已退出人員
if(i==3)
{a[x]=false;i=0;k--;}//當數到3時,退出人員設為false,剩餘人數減1,i設為0,重新計數
}
cout<<"留下來的人序號為:"<<x<<" ";
delete[]a;
cin.get();
cin.get();//等待下一次鍵擊關閉窗口
return0;
}
法二(遞歸法):
此題可用數學方法求解。
設有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<iostream>
usingnamespacestd;
constintm=3;
intmain()
{
intn,f=0;
cin>>n;
for(inti=2;i<=n;i++)
f=(f+m)%i;
cout<<f+1<<endl;
}
『伍』 C語言有n個人圍成一圈,順序排號。從第一個人開始報數(從1到3報 數)凡報到3的人退出圈子麻煩注釋下代碼
#include<stdio.h>
#define N 5//人數
void main()
{
int a[N]={0},i=0,out_n=0,call_n=0,*p;
p=a;
while(1){//循環報數
if(*p==0){//如果健在
if(out_n==(N-1))break;//如果僅剩一人
call_n++;//報數
call_n%=3;//最大為3,到了3就從0開始
if(call_n==0){*p=1;out_n++;}//為0(即3)出局
}
p++;if(p==a+N)p=a;//循環轉向下一人
}
printf("最後剩餘者的編號是:%d ",p+1-a);
}
(5)c語言n個人圍成一圈擴展閱讀:
printf()函數是格式化輸出函數,一般用於向標准輸出設備按規定格式輸出信息。在編寫程序時經常會用到此函數。
函數的原型為:int printf(const char*format,...);函數返回值為整型。若成功則返回輸出的字元數,輸出出錯則返回負值。
printf()函數的調用格式為:
printf("<;格式化字元串>",<參量表>);
其中格式化字元串包括兩部分內容:一部分是正常字元;這些字元將按原樣輸出;另一部分是格式化規定字元,以"%"開始,後跟一個或幾個規定字元,用來確定輸出內容格式。
參量表是需要輸出的一系列參數,其個數必須與格式化字元串所說明的輸出參數個數一樣多,各參數之間用","分開,且順序一一對應,否則將會出現意想不到的錯誤。
規定符
%d十進制有符號整數
%u十進制無符號整數
%f浮點數
%s字元串
%c單個字元
%p指針的值
%e指數形式的浮點數
%x,%X無符號以十六進製表示的整數
%o無符號以八進製表示的整數
%g把輸出的值按照%e或者%f類型中輸出長度較小的方式輸出
%p輸出地址符
%lu 32位無符號整數
%llu 64位無符號整數
『陸』 C語言編程:有n個人圍成一圈,按順序從1到n編號。從第一個人開始,報到3的人退出圈子。
這個問題叫約瑟夫環,就是一群人圍成一圈,從第一個人開始,報到3的出列,看最後留下誰。
這個可以用循環鏈表來實現,你也可以網路下,網路里有許多關於約瑟夫環的問題!
這個是我以前寫的代碼,你可以參考下,n取的10
#include
struct
serial
{
int
num;
struct
serial
*next;
};
void
main()
{
int
i;
struct
serial
peo[100],*p,*q;
for(i=0;i<10;i++)
peo[i].num=i+1;
for(i=0;i<9;i++)
peo[i].next=&peo[i+1];
peo[9].next=peo;
q=p=peo;
while(p!=p->next
)
{
for(i=0;i<2;i++)
{
q=p;
p=p->next;
}
q->next
=p->next
;
printf("被刪除的元素:%-4d\n",p->num);
p=q->next
;
}
printf("\n最後報號出來的是原來的:%d\n",p->num);
getchar();
}
『柒』 C語言編一個程序:有N個人排成一圈
#include<stdio.h>
#define M 10 /*M是總人數*/
#define N 3 /*循環為3*/
void main(void)
{
int a[M], b[M]; /*數組a存放圈中人的編號,數組b存放出圈人的編號*/
int i, j, k;
for(i = 0; i < M; i++) /*對圈中人按順序編號1—M*/
a[i] = i + 1;
for(i = M, j = 0; i > 1; i--){
/*i表示圈中人個數,初始為M個,剩1個人時結束循環;j表示當前報數人的位置*/
for(k = 1; k <= N; k++) /*1至N報數*/
if(++j > i - 1) j = 0; /*最後一個人報數後第一個人接著報,形成一個圈*/
b[M - i] = j? a[j - 1]: a[ i - 1]; /*將報數為N的人的編號存入數組b*/
if(j)
for(k = --j; k < i; k++) /*壓縮數組a,使報數為N的人出圈*/
a[k] = a[k + 1];
}
for(i = 0;i < M – 1; i++) /*按次序輸出出圈人的編號*/
printf(「%6d」, b[i]);
printf(「%6d\n」, a[0]); /*輸出圈中最後一個人的編號*/
}
(2)上面的演算法效率不高,用標記的方法修改(1)中程序,使之效率提高
代碼如下:
#include <stdio.h>
#define M 10
#define N 3
#define START 0
void main(void)
{
int a[M], i = 0, k, count = 0;
while(i++ < M)
a[i - 1] = i;
for(i = START; count <= M - 1; count++)
{
for(k = 1; k <= N; a[i++] && ++k) /*a[i]若為零則++k運算被忽略*/
if(i > M - 1)
i = 0;
printf("%d ", i ? a[i - 1] : a[M - 1]);
a[(i ? (i - 1) : (M - 1))] = 0;
}
}
有不懂可以給我留言。這是我們剛做的實驗,剛好被你碰到了,哈哈
『捌』 c語言:有n個人圍成一圈,從第一個人開始報數1、2、3,每報到3的人退出圈子。編程使用【鏈表】找出
#include<iostream>
#include<malloc.h>
using namespace std;
struct node
{
int no; //代表編號結點的數據
int code;//代表密碼結點的數據
node *next;//代表後一個結點的地址
};
int main()
{
int m,n,i,j;
node *p,*q,*first;
m=3;
cout<<"請輸入人數 n:";
cin>>n;
for(i=1;i<=n;i++)
{
if(i==1)
{
first=p=(node*)malloc(sizeof(node));
if(p==0)
return 0;
}
else
{
q=(node*)malloc(sizeof(node));
if(q==0)
return 0;
p->next=q;
p=q;
}
cout<<"請輸入第 "<<i<<" 個人的密碼: ";
cin>>(p->code);
p->no=i;
}
p->next=first; //讓表尾指向表頭形成循環鏈表
p=first;
cout<<"出列順序為: ";
for (j=1;j<=n;j++)
{
for(i=1;i<m;i++,p=p->next);
m=p->code;
cout<<p->no<<" ";
p->no=p->next->no;
p->code=p->next->code;
q=p->next;
p->next=p->next->next;
free(q);
}
cout<<endl;
return 0;
}
『玖』 c語言,有n個人圍成一圈,按順序從1到n編好號。從第一個人開始報數,報到m(m<n)的人退出圈子
#include<stdio.h>
int main()
{int m,n,a[100],out=0,i,j=0;
scanf("%d%d",&n,&m); /*輸入m,n*/
for(i=0;i<n;i++)
a[i]=i+1;
while(out<n)
{for(i=0;i<n;i++)
{if(a[i]!=0)
j++;
if(j==m)
{printf("%d\n",a[i]);out++;j=0;a[i]=0;} /*依次列印退出人的編號*/
if(i==n-1) break;
}
}
i=0;
if(a[i]!=0)
{printf("%d",a[i]);i++;} /*最後列印剩下一人的編號*/
}
請採納