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;
}