GDPU 竞赛技能实践 天码行空1 C语言复习

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

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值