C语言/C++常见习题问答集锦(六十九) 之最后的赢家

C语言/C++常见习题问答集锦(六十九) 之最后的赢家

程序之美

在这里插入图片描述

1、C语言版 顺序栈的数据结构。

#include<stdio.h>
#include<stdlib.h>
 
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define MAXSIZE 100
 
typedef int ElemType;
typedef int Status;
 
/* 顺序栈的存储结构 */
typedef struct{
    int *top;   // 栈顶指针
    int *base;  // 栈底指针
    int stackSize;  // 最大容量
}SqStack;
 
/**
 * @brief 初始化顺序栈
 */
Status initStack(SqStack *s){
    s->base = (ElemType*)malloc(sizeof(ElemType));
    if(!s->base)    return ERROR;
    s->top = s->base;
    s->stackSize = MAXSIZE;
    return OK;
}
 
Status clearStack(SqStack &s){
    if(s.base)  s.top = s.base;
    return OK;
}
 
Status destroyStack(SqStack *s){
    // if(s->base)

	return OK;
}
 
/**
 * @brief 入栈
 */
Status push(SqStack *s,int e){
    if((s->top-s->base) == s->stackSize)    return ERROR;
    *s->top = e;
    s->top++;
}
 
/**
 * @brief 出栈
 */
Status pop(SqStack *s,int e){
    if(s->top == s->base)   return ERROR;
    --s->top;
    e = *s->top;
}
 
/**
 * @brief 遍历顺序栈
 */
Status displayStack(SqStack s){
    if(s.top == s.base) return ERROR;
 
    while(s.base < s.top){
        printf("%d ",*(s.base++));
    }
    printf("\n");
}
 
/**
 * @brief Get the Length object 获取顺序栈的长度
 */
int getLength(SqStack s){
    return s.top - s.base;
}
 
int main(){
    SqStack stack;
    ElemType e;
    // 初始化
    initStack(&stack);
    // 入栈
    push(&stack,5);
    push(&stack,8);
    push(&stack,0);
    push(&stack,3);
    push(&stack,9);
    // 遍历
    printf("displayStack: ");
    displayStack(stack);
    // 清空 获取长度
    clearStack(stack);
    printf("getLength: %d\n",getLength(stack));

	return 0;
}

运行结果:
在这里插入图片描述

2、有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

初学者可用数组来实现。
我们先初始化一个[1-10]的数组,
每次删除一个元素,我们就把该元素的值标记为-1,表示该元素不可用了,这样非-1的元素就是可用元素,10个人的话,删除到最后,就只剩下一个可用元素,它的值为4

C语言版本:
解法一:

#include<stdio.h> 
main() 
{ 
int a[100]; 
int i,n,p=0,q; 
printf("input number:"); 
scanf("%d",&n); 
q=n; 
for(i=0;i<n;i++) a[i]=i+1; 
for(i=0;;i++) 
 { 
 if(i==n) i=0; //当i++一直到n时,肯定有一些没有被选到,比如我们输入8,第一轮是3,6被赋值0,当i=8时,继续下一轮//
 if(a[i]!=0) p++;//我们下面定义的是当循环到三时,就赋值0,所以这边等0的不考虑在内// 
 else continue; 
 if(p%3==0)//这个就是从0一直加,到三的倍数就赋值为0,从而就达到我们的目的//
  {a[i]=0;q--;} //上面q=n;表明q==n,只有一个为0就减一,为下面做铺垫//
 if(q==1) break; //当剩下最后一个就输出//
 } 
for(i=0;i<n;i++) 
if(a[i]!=0) 
printf("spare: %d\n\n",a[i]); 
}

解法二:

#include<iostream>  
  
using namespace std;  
  
int main()  
{  
    int num[50];  
  
    int i,j,k,m,n;  
  
    int *p;  
  
    cout<<endl<<"请输入总人数:"<<endl;  
  
    cin>>n;  
  
    p=num;  
  
    for(i=0;i<n;i++)  
    {  
        *(p+i)=i+1;   //以1至n为序,给每个人编号  
    }  
  
    i=0;    //i为每次循环时计数变量  
  
    k=0;    //k为按1 2 3报数时的计数变量  
  
    m=0;    //m为退出人数  
  
    while(m<n-1)  //当退出人数比n-1少时(即未退出人数大于1时)执行循环体  
    {  
        if(*(p+i)!=0)  
        {  
            k++;  
        }  
  
        if(k==3)    //将退出人的编号置为0  
        {  
            *(p+i)=0;  
  
            k=0;  
  
            m++;  
        }  
  
        i++;  
  
        if(i==n)  
        {  
            i=0;//报数到尾后i恢复为0  
        }  
    }  
  
    while(*p==0)  
    {  
        p++;  
    }  
  
    cout<<"最后一个是"<<*p<<" 号!"<<endl;  
  
    return 0;  
}  

解法三:

#include <stdio.h> 

 int M = 3; 

int main() 
{ 
    int n, s = 0; 
    scanf("%d", &n); 
    for (int i = 2; i <= n; ++i) 
        s = (s+M)%i; 
    printf("%d\n", s+1); 
    return 0; 
}

C++版本:


#include<iostream>
using namespace std;
int main() {
	int n;
	cin >> n;//输入要玩的人数
	int *p = new int[n];//动态创建一个大小为输入的人数的一位数组
	for (int i = 0; i < n; i++)
		p[i] = 1;//将数组内每个值都设置为1,作为还在圈内的人
	int k = 0;
	int count = 0;//报数
	int countnum = n;//在进行游戏的人数
	while (countnum>1) {//游戏一直进行,直到圈内的人数为1,而他就是最后留下来的人
		if (p[k] == 1)//如果他是1,就说明他还在圈内,他就报数
			count++;
		if (count==3) {//报数从1开始,报到3的就退出圈子
			p[k] = 0;//将数组值设为0,代表他退出圈子
			count = 0;//重新开始计数
			countnum--;//圈内进行游戏的人少一个
		}
		k++;//数组一个个循环下去
		if (k == n)//如果数组等于输入的人数,就说明下一个报数的人就是第一个人,才能实现这个游戏的循环
			k = 0;//游戏的第一个人,就是数组的第一位,为p[0]
	}
	for (int i = 0; i < n; i++) {
		if (p[i] == 1)//循环这个数组,他的数值是1,就说明他是最后留下来的人
			cout << i+1 << endl;//数组从0开始,得加1,才是原来游戏的第几位
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五一编程

程序之路有我与你同行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值