1. 约瑟环
圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。从第一个人开始数数,数到第m个人,立即赶走该人;然后从被赶走的人之后开始数数,再将数到的第m个人赶走……依此方法不断赶走围坐在圆桌上的人。
预先应如何安排这些好人与坏人的座位,能使得在赶走n个人之后,圆桌上围坐的剩余的n个人全是好人?
#include <iostream>
#include <string>
using namespace std;
// 约瑟环问题
void josephus(int n, int m) {
int sum = 2 * n;//sum 为总人数
bool set[sum] = {false};// true表示被赶走的
int cur = 0;//当前未数到的座位下标
while (n--)//需要赶走 n 个人
{
int mm = m;//需要数 m 个人
while(mm--)
{
if(set[cur])//座位已空的不数数
mm++;
cur = (cur + 1) % sum;//当前未数到的座位下标后移
}
//需要赶走的是 当前未数到的座位 的 前一个座位(注意循环数组的[0-1]越界问题)
int idx = (cur - 1 + sum) % sum;
set[idx] = true;//赶走
}
cout << "座位安排:";
for(int i = 0; i < sum; i++)
{
string man = set[i] ? "坏人" : "好人";
cout << "[" <<i+1 <<"]" << man;
if(i != sum - 1)
cout << ",";
}
}
int main() {
int n, m;
printf("请输入好人的数量 n 和 特定的数 m\n");
scanf("%d %d", &n, &m);
josephus(n, m); // 调用函数解决约瑟环问题
return 0;
}
输入:
5 5
输出:
座位安排:[1]好人,[2]坏人,[3]好人,[4]好人,[5]坏人,[6]坏人,[7]好人,[8]好人,[9]坏人,[10]坏人
2. 回文串
利用栈与队列,判断一个句子是否回文。(如“madam, i am a man.”,去掉标点便是回文)
#include <iostream>
#include <stack>
#include <queue>
#include <cctype>
using namespace std;
// 将句子中的标点符号去除并转换为小写字母
string preprocessSentence(string sentence) {
string processedSentence = "";
for (int i = 0; i < sentence.length(); i++) {
if (isalpha(sentence[i])) { // 如果是字母
processedSentence += tolower(sentence[i]); // 转换为小写字母并添加到处理后的句子中
}
}
return processedSentence;
}
// 判断句子是否回文
bool isPalindrome(string sentence) {
stack<char> stack; // 创建一个栈
queue<char> queue; // 创建一个队列
sentence = preprocessSentence(sentence); // 预处理句子
for (int i = 0; i < sentence.length(); i++) {
stack.push(sentence[i]); // 将字符压入栈
queue.push(sentence[i]); // 将字符加入队列
}
while (!stack.empty() && !queue.empty()) {
char stackTop = stack.top(); // 获取栈顶元素
char queueFront = queue.front(); // 获取队列头部元素
stack.pop(); // 弹出栈顶元素
queue.pop(); // 弹出队列头部元素
if (stackTop != queueFront) { // 如果栈顶元素和队列头部元素不相等,则不是回文
return false;
}
}
return true; // 如果栈和队列都为空,则是回文
}
int main() {
string sentence;
cout << "请输入一个句子:";
getline(cin, sentence); // 获取用户输入的句子
if (isPalindrome(sentence)) { // 判断是否是回文
cout << "该句子是回文。" << endl;
} else {
cout << "该句子不是回文。" << endl;
}
return 0;
}
3. 递归汉诺塔
#include <stdio.h>
// 汉诺塔函数,n表示盘子的数量,from表示起始柱子,to表示目标柱子,aux表示辅助柱子
void hanoi(int n, char from, char to, char aux) {
if (n == 1) {
printf("把 1 号盘子从 %c 移到 %c\n", from, to);
return;
}
// 将除最底下的盘子外的上面所有盘子从起始柱子移动到辅助柱子
hanoi(n-1, from, aux, to);
printf("把 %d 号盘子从 %c 移到 %c\n", n, from, to); // 将最底下的盘子从起始柱子移动到目标柱子
// 将之前移动到辅助柱子的盘子们从辅助柱子移动到目标柱子
hanoi(n-1, aux, to, from);
}
int main() {
int n;
printf("请输入需要移动的盘子数:\n");
scanf("%d", &n);
printf("移动步骤:\n");
hanoi(n, 'A', 'C', 'B'); // 调用汉诺塔函数开始移动
return 0;
}