PTA 约瑟夫环
约瑟夫环
作者 吴锦桥 单位 西北农林科技大学
有N个人围成一圈(编号为1~N),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数……直到最后只剩下一个人时为止。请问此人原来的编号是多少?
输入格式:
在一行中给出1个不超过100的正整数N。
输出格式:
在一行中输出最后剩下那个人的编号。
输入样例:
10
输出样例:
4
分析:
- 方法一:公式法。该题目最后能推导出一个递归公式:f(N,M)=(f(N−1,M)+M)%N;其中f(N,M)表示,N个人报数,每报到M时杀掉那个人,最终胜利者的编号;f(N−1,M)表示,N-1个人报数,每报到M时杀掉那个人,最终胜利者的编号
#include<iostream> #include<set> using namespace std; int main(){ int n,f=0; cin>>n; for (int i = 1; i <= n; i++) f = (f + 3) % i; cout << f + 1 << endl; }
- 方法二:首先使用一个队列来模拟。然后使用一个计数器
count
来记录当前报数的次数。每次循环中,如果count
等于3,说明当前这个人需要退出,我们就从队列中弹出他。否则,我们将队首的人移到队尾,并弹出他,模拟他报数后移动到下一个人的过程。最后,当队列中只剩下一个人时,他就是最后的胜利者,输出他的编号
#include <iostream> #include <queue> using namespace std; int main() { int n; cin >> n; queue<int> q; for (int i = 1; i <= n; i++) { q.push(i); } int count = 0; while (q.size() > 1) { count++; if (count == 3) { q.pop(); count = 0; } else { q.push(q.front()); q.pop(); } } cout << q.front() << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了