⑴ c語言 報數問題
方法一:(推薦)不受人數限制,因為採用的動態分配
#include <stdio.h>
#include <malloc.h>
/*********************************************************************
*以循環隊列的數據結構實現
*時間復雜度T(n)
*採用循環隊列數據結構,使得每次對數組的訪問次數減少到最少
**********************************************************************/
int main(void)
{
//定義並初始化各種變數
int i=0,//控制變數
num=0,//人數
die=0,//報數值
front,//隊頭位置
rear,//隊尾位置
temp=0;//中間變數
do
{
printf("\n請輸入人數(輸入小於0退出):");
scanf("%d",&num);
printf("\n請輸入報數值:");
scanf("%d",&die);
int *cycle=(int *)malloc((num+1)*sizeof(int));//多申請一個空間,在循環過程中方便處理
//依次編號,一號元素為0,暫時閑置
for(i=0;i<=num;i++)
{
cycle[i]=i;
}
//置隊頭和隊尾的位置
front=1;
rear=num;
i=1;//報數器置1,開始報數
while(front!=rear)//當隊列中元素不止一個時,循環
{
//備份出隊數據
temp=(rear+1)%(num+1);//在位置rear後預留一個位置,以免有元素入隊
cycle[temp]=cycle[front];
front=(front+1)%(num+1);//隊頭元素出隊,隊頭位置加1
//如果出隊的人報數符合條件
if(i==die)
{
i=1;//報數重新置1,開始報數
printf("%d出隊\n",cycle[temp]);//顯示出隊的元素
}
//如果出隊的人報數不符合條件
else
{
i++;//報數值增1
//隊尾插入剛出隊的元素
rear=(rear+1)%(num+1);
cycle[rear]=cycle[temp];
}
}
printf("倖存者是%d\n",cycle[front]);
free(cycle);
}while(num!=0);
return 0;
}
方法二:(按你的要求)
#include <stdio.h>
/*********************************************************************
*以純粹的思維方法實現
*時間復雜度T(n)
*過程繁瑣,而且也不容易理解
*********************************************************************/
void main(void)
{
int result(int *p,int n,int m);
int i=0,m=0,n=0;
int num[50];
int *p;
for(;;)
{
printf("輸入人數和報數值:");
scanf("%d%d", &n, &m);
for(i = 0; i < n; i++)
num[i] = i + 1;
p = num;
cout<<"The last one is NO."<<result(p,n,m)<<endl;
}
}
int result(int *p,int n,int m)
{
int i=0;
for(i=0;i<n;i++)
p[i]=i+1;
i=0; // i為每次循環時計數變數
int k=0; // k為按1,2,3...m報數時的計數變數
int die=0; // die為退出人數
while (die<n-1) // 當退出人數比n-1少時(即未退出人數大於1時)執行循環體
{
if (p[i]!=0) k++; //如果編號為0,就不報數;如果編號不為0,報數加1
if (k==m) // 將退出的人的編號置為0
{
printf("%d退出\n",p[i]);
p[i]=0;
k=0;//重新開始報數
m++;//退出人數加1
}
i++;
if (i==n) i=0; // 報數到尾後,i恢復為0
}
while(*p==0) p++;
return *p;
}
⑵ C語言 報數出列
#include<stdio.h>
#include<math.h>
void main()
{
int sint[10000]={0};
int dint[10000]={0};
int s=0,d=0;
int i=1,j=0,n=0,m=0;
long l;
int ln=0;
while (1)
{
printf("請輸入循環隊列的n和m(n<10000,m<10000)(格式:n m):");
scanf("%d %d",&ln,&m);
fflush(stdin);
if ( ( ln>0 && ln <10000 ) && ( m>0 && m <10000 ) )
break;
else
printf("\nERROR:錯誤,輸入有誤,重新輸入!\n");
}
n=ln;
for (i=0;i<n;i++)
{
sint[i]=i+1;
}
l=0;
while (n>=0)
{
l++;
if (l%m==0)
{
dint[d]=sint[s];
for(j=s;j<n;j++)sint[j]=sint[j+1];
sint[j+1]=0;
n--;
d++;
}else
s++;
if(s==n) s=0;
}
for (i=0;i<ln;i++)printf("%d ",dint[i]);
printf("\n");
}
示例:
請輸入循環隊列的n和m(n<10000,m<10000)(格式:n m):20 2
2 4 6 8 10 12 14 16 18 20 3 7 11 15 19 5 13 1 17 9
⑶ C語言,報數出列
intn,m,loop;
intcurrentNum;
intoutNum;
int*state;
printf("輸入人數:");
scanf("%d",&n);
printf("輸入要報的數:");
scanf("%d",&m);
//構造一個狀態表,0表示還在圈內,1表示已經出圈
state=(int*)malloc(sizeof(int)*n);
for(loop=0;loop<n;loop++)
{
state[loop]=0;
}
currentNum=n;
while(1)
{
//圈裡只有一個人
if(currentNum==1)
{
break;
}
outNum=m%currentNum;//計算是第幾個人出圈
if(outNum==0)
{
outNum=currentNum;
}
//找到出圈的人
for(loop=0;loop<n;loop++)
{
if(state[loop]==0)
{
outNum--;
}
if(outNum==0)
{
break;
}
}
state[loop]=1;//表示已經出圈
currentNum--; //全人數減少
}
for(loop=0;loop<n;loop++)
{
if(state[loop]==0)//找到最後的那一個人
{
break;
}
}
printf("最後出圈的人編號是:%d ",loop+1);
free(state);
⑷ 報數(C語言)
方法一:
#include<stdio.h>
void main()
{int a[100][100],n,m,i,j; /*a[100][100]只是隨機設置的一個數組,需要時可設得更大或更小*/
K:scanf("%d:%d",&n,&m); /*注意輸入格式,其中的":",表示兩者的關系為"報數->取數"的關系*/
if(n>0&&m>0)
{for(i=1;i<=n;i++)
a[1][i]=i;
for(i=1;i<=n;i++)
{for(j=m%(n+1-i)+1;j<=(n+1-i);j++) /*將取余後右邊第一項,作為下一次數數的最前一項,依次遞增*/
a[i+1][j-m%(n+1-i)]=a[i][j];
for(j=1;j<=m%(n+1-i);j++) /*將取余後左邊第一項,作為下一次數數的最後一項,
a[i+1][(n+1-i)-m%(n+1-i)+j]=a[i][j]; 依次遞減;並將取到的數,依次放在下一次數數的外層*/
printf("f(%d:%d)(%d)=%d\n",n,m,i,a[i+1][(n+1-i)]);}} /*輸出每一次報數時,取到的數*/
else printf("No effect!\n");
goto K; /*goto語句使程序可重新輸入其他的情況,如"13:3"表示13個人,每報3次數,退出一個人*/
getch();}
方法二:
#include<stdio.h>
void main()
{int a[100],i,j,n,m;
K:scanf("%d:%d",&n,&m);
for(i=1;i<=n;i++)
a[i]=i;
for(j=0,i=1;i<=n;i=i%n,i++) /*i=i%n用來實現當i從1到達n,將重新回到1*/
{if(a[i]!=0) {j++; if(j%m==0) printf("f(%d)=%d\n",j/m,a[i]),a[i]=0;}
if(j/m==n) break;} /*反復計數,將數過的數標記為0,下次數數時不再數它*/
goto K;
getch();}