fjut-quiz-2022-10-26/quiz4/quiz4.cpp

137 lines
4.3 KiB
C++
Raw Normal View History

#include <iostream>
#include <cstring>
2022-10-27 00:00:09 +08:00
#include <sstream>
#include <limits.h>
2022-10-27 00:37:35 +08:00
/**
*
*
*/
struct node {
2022-10-27 00:37:35 +08:00
int id; /** 链表数据体,也就是小人的 id */
node* next;
node* prev;
};
2022-10-27 00:37:35 +08:00
/**
* ,
* .
*
* >
* >
*
* ""
*
*
* ****
*
* @param first ""
* @param curr ""
*/
void insert_one (node* first, node* curr) {
node* insertion_prev = (*first).prev;
node* insertion_next = first;
(*insertion_next).prev = curr;
(*insertion_prev).next = curr;
(*curr).next = insertion_next;
(*curr).prev = insertion_prev;
}
2022-10-27 00:37:35 +08:00
/**
* .
*
*
*
*
*
* @param removal
*/
void remove_one (node* removal) {
node* removal_prev = (*removal).prev;
node* removal_next = (*removal).next;
(*removal_next).prev = removal_prev;
(*removal_prev).next = removal_next;
delete removal;
}
int main () {
2022-10-27 00:37:35 +08:00
// 接受用户输入中
/** 用户输入的小人数量 */
int n = 0;
2022-10-27 00:37:35 +08:00
while (n == 0) { // 由于任何输入问题导致没有成功获得输入数据都会重新进行输入请求
std::string input;
int input_n;
std::cout << "请输入小人个数: ";
std::cin >> input;
2022-10-27 00:37:35 +08:00
try { // 尝试解析用户输入
input_n = stoi(input);
if (input_n < 1) throw std::exception();
2022-10-27 00:37:35 +08:00
} catch (std::out_of_range) { // 如果输入的数字太大以至于超出了系统处理范围的报错
std::cout << "你输入的数字 \"" << input << "\" 太大了,它最大只能是 " << INT_MAX << std::endl;
continue;
2022-10-27 00:37:35 +08:00
} catch (std::exception) { // 如果输入的不是一个数字,或者输入的数字不符合要求(当然不会有小于 0 个人0 个人(没有人)也显然不符合预设现实)的报错
std::cout << "你的输入是 \"" << input << "\", 但小人的数量必须是一个大于 0 的整数!" << std::endl;
continue;
}
2022-10-27 00:37:35 +08:00
// 二次确认输入数值(防呆)
std::cout << "小人个数为 " << input_n << " ? [y/n]";
std::cin >> input;
if (input == "y")
n = input_n;
}
2022-10-27 00:37:35 +08:00
// 招募第一个小人(为链表创建 "头",同时也构建出最小的链表体)
node* first = new node;
(*first).id = 1;
(*first).prev = first;
(*first).next = first;
2022-10-27 00:37:35 +08:00
/** 记录这个队里目前有多少人(记得手动操作) */
int count = 1;
std::cout << "招募了小人 #" << 1 << " ." << std::endl;
2022-10-27 00:37:35 +08:00
// 招募从第 2 个开始的剩下的小人(按照顺序一个个把它们加到链表尾)
for (int i = 2; i <= n; i++) {
node* curr = new node;
(*curr).id = i;
insert_one(first, curr);
count++;
std::cout << "招募了小人 #" << 1 << " , 它前面是 #" << (*(*curr).prev).id << " , 它后面是 #" << (*(*curr).next).id << std::endl;
}
2022-10-27 00:37:35 +08:00
/**
* .
*
*
*/
2022-10-27 00:00:09 +08:00
std::stringstream out_roll;
2022-10-27 00:37:35 +08:00
int counting = 0;
node* next_one = (*first).prev;
2022-10-27 00:37:35 +08:00
while (count > 1) { // 让大家轮流出队直到队里只剩下最后一个人
node* current = next_one;
next_one = (*next_one).next;
counting++;
std::cout << "小人 #" << (*current).id << " 数到了" << counting;
if (counting == 3) {
2022-10-27 00:00:09 +08:00
out_roll << "#" << (*current).id << " ";
remove_one(current);
counting = 0;
count--;
std::cout << " , 出列!还剩下 " << count << "个小人。";
} else {
std::cout << " .";
}
std::cout << std::endl;
}
2022-10-27 00:37:35 +08:00
// 出队总结
std::cout << "=====" << std::endl
<< "最终剩下了小人 #" << (*next_one).id << " !" << std::endl;
2022-10-27 00:00:09 +08:00
std::cout << "小人的出列顺序是: " << out_roll.str() << "." << std::endl;
return 0;
}