新兵队列训练C++(简单实现)

题目:某部队进行新兵队列训练,将新兵从1开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始1至2报数,凡报到2的出列,剩下的向小序号方向靠拢,再从头开始进行1至3报数,凡报到3的出列,剩下的向小序号方向靠拢,继续从头开始进行1至2报数,以后从头开始轮流进行1至2报数、1至3报数直到剩下的人数不超过三人为止。编写程序,输入数N为最开始的新兵人数(20 < N < 6000),输出剩下的新兵最初的编号。

输入样例:

21

输出样例:

1 7 19

来自编程小白(没错就是我)的想法:

  • 因为N是变量,所以用new实现内存分配(讲真,学校网站用的在线编译器太老了,不过问题不大),支持新标准C++的可以直接int list[N]
  • 根据题目中“像小序号靠拢”,说明每次有人出队列,第二次报数的时候,人们在队列中的位置会发生变化,但是最后还要输出人们的起始位置,所以我就想用一个结构体,存储起始位置和新位置。
  • 如果用数组的话,可以让他们的位置编号和数组的索引相对应。
  • 由2 可知需要一个函数来赋予他们新的位置,然后出队列的时候把新位置的值变成0,表示他出去了。
  • 使用一个变量count来区分是1-3还是1-2
  • 由于题目要求剩余人数不大于3个的时候停止,所以需要一个记录队列中有效人数的数字num
  • 输出的时候注意最后一位没有空格

贴代码:

#include<iostream>

struct element {
	int festnum;
	int Newnum;
};

void renum(element* list, int N ) {      //给他新的编号
	int n = 1;
	for (int i = 0; i < N; i++) {
		if (list[i].Newnum != 0) {
			list[i].Newnum = n;
			n++;
		}
	}
}                                                 

void gout(element* list,int N,int count,int& num) {
	for (int i = 0; i < N; i++) {
		if (list[i].Newnum % count == 0 && list[i].Newnum != 0) {
			list[i].Newnum = 0;
			num--;
		}
	}
}

int main() {
	int N;
	element* list;
	int count = 2;
	std::cin >> N;
	list = new element[N];
	int num = N;
	for (int i = 0; i < N; i++) {
		list[i].festnum = i+1;  //记录编号
		list[i].Newnum = list[i].festnum;
	}                          //删除完一次就重新给一个编号

	while (num > 3) {
		gout(list, N, count, num);
	
		renum(list, N);
		
		if (count == 2) count = 3;
		else count = 2;
	}
	int x = 1;
	for (int i = 0; i < N; i++) {
		if (list[i].Newnum != 0&&x!=num) {
			std::cout << list[i].festnum<<" ";
			x++;
			continue;
		}
		if (list[i].Newnum != 0 && x == num) {
			std::cout << list[i].festnum;
			break;
		}
	}
	delete[] list;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值