c语言报数问题
❶ c语言报数问题
设有n个人围坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止。现要求按出圈次序,每10人一组,给出这n个人的顺序表。请考生编制函数Josegh()实现此功能并调用函数WriteDat()把结果p输出到文件OUT.DAT中。
设n=100,c=1,m=10.
(1)将1到n个人的序号存入一维数组p中;
(2)若第i个人报数后出圈,则将p[i]置于数组的倒数第i个位置上,而原来第i+1个至倒数第i个元素依次向前移动一个位置;
(3)重复第(2)步直至圈中只剩下p[1]为止。
部分源程序已给出。
请勿改动主函数main()和输出数据函数writeDat()的内容。 #include <stdio.h>
#define N 100
#define S 1
#define M 10int p[100],n,s,m;
void WriteDat(void);void Josegh(void)
{}void main()
{
m=M;
n=N;
s=S;
Josegh();
WriteDat();
}void WriteDat(void)
{
int i;
FILE *fp;
fp=fopen("out.dat" ," w" );
for(i=N-1;i>=0;i--){
printf(" %4d" ,p[i]);
fprintf(fp," %4d" ,p[i]);
if(i % 10==0){
printf("\n" );
fprintf(fp, "\n" );
}
}
fclose(fp);
}
/* 注:题中第一个for()循环是先对数组p赋初值。在第二个for()中用i来控制没出圈的
总人数,s1=(s1+m-1)%i的作用是找出报数后出圈人的下标,其中对i求余的作用是使报
数按圈进行(即报到尾后又从头报),该算法在很多题目中都用到。由于求余的作用当
报数正好到最后一个时s1为0,故而要进行if(s1==0)的判断。内嵌的for()循环是将出圈
以后的人依次往前移。*/
void Josegh(void)
{
int i,j,s1,w;
s1=s;
for(i=1;i<=n;i++)
p[i-1]=i;
for(i=n;i>=2;i--)
{s1=(s1+m-1)%i;<br>if(s1==0)<br>s1=i;<br>w=p[s1-1];<br>for(j=s1;j<i;j++)<br>p[j-1]=p[j];<br>p[i-1]=w;<br>}
} 这的问题和这个一样,看看吧,应该能解决了
❷ C语言围圈报数问题
n=10
m=3
1 2 3 4 5 6 7 8 9 10
1 2 3 1 2 3
你告诉我第二个人怎么算出7的,这题目是来搞笑的么!
❸ C语言,报数问题
这个问题是着名的Josephus排列,就是要用指针和链表才是正确的思路。不用指针就暂时放置这题。若有非指针解你完全可以采纳他,若没有用指针正确写的,请结贴。给你个用指针并且还用链表的代码参考以便你在未来学会指针后来阅读。
http://blog.csdn.net/z84616995z/article/details/37969175
❹ C语言编程报数问题
自己写的,完整的程序,并附有测试的数据。
分别用链表和顺序表实现了。楼主可以好好看看。
http://..com/question/411820901.html?oldq=1
代码我就不重复贴了。好运!
❺ c语言中报数问题
程序没具体看
10%99=10不是0因为C语言%是求余 / 才是相除取整(舍余舍小数)
❻ 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>
int main()
{
int a[1000], i, n, k, m=0, left;//left用来记录剩余的非0数据的个数
int *p = a + 1;
scanf("%d%d", &n, &k);
left = n;//初始化剩余非0数据个数
for(i=1; i<=n; i++)
a[i] = i;
for(p; p<=a+n; p++) {
if(*p != 0) {
m++;
}
if((m % k == 0) && (m != 0)) {//m != 0这个条件很重要,用来避免重复
*p = 0;
m = 0;//每数到k将m值置0
left--;//剩余非0数据减1
if (left < k)//剩余个数小于k,则退出循环
break;
}
if(p == a + n)//数到最后一个的时候,从头开始数
p = a ;//这里p的值应该改为a;因为进入下一轮循环的时候,在for(p; p<=a+n; p++)中是先执行p++的,执行p<=a+n是p的值为p+1了
}
p = a + 1;
for(p; p<=a+n; p++)
printf("%d ",*p);
return 0;
}
❽ c语言围圈报数问题
#include<stdio.h>
#defineM10
#defineN3
voidmain(void)
{
inta[M],b[M];
inti,m,k;
for(i=0;i<M;i++)
a[i]=i+1;
m=0;
i=0;
while(m<10){
k=0;
while(1){
if(a[i]>0)
{
k++;
if(k>=3)
break;
}
i=(i+1)%M;
}
b[m]=a[i];
a[i]=0;
++m;
i=(i+1)%M;
}
for(k=0;k<M;++k)
{
printf("%d",b[k]);
}
}
❾ C语言 报数问题
#include<stdio.h>
int main(void)
{
int a[9999],n,i,count,num,*p;
p=&a[0];
count=1;
n=i=num=0;
printf("Input n(n must be a natural number less than 10000):");
scanf("%d",&n);
if(n<=10000)
{
for(i=0;i<n;i++)
a[i]=i+1;
while(num<n-1)
{
count++;
p++; //这里就有越界的可能(p>&a[n-1]),如果这里越界了,那下
面的循环就不会执行了,那么p就一直++,直到num==n-1
if(p>&a[n-1]) //所以这里就要判断一下,或者开始时就把a的所有
元素全部初始化为0,就不用这个判断了
p=&a[0];
while(*p==0)
{
p++;
if(p>&a[n-1])
p=&a[0];
}
if(count%3==0)
{
*p=0;
num++;
}
}
while(*p==0)
{
p++;
if(p>&a[n-1])
p=&a[0];
}
printf("Last No. is:%d",*p);
}
else
printf("%d is out of range of valid values.",n);
return 0;
}
❿ C语言报数游戏,从某一个数开始,另一个人报数比第一个人加一或二,报到24着输
咨询记录 · 回答于2021-11-13