题目:约瑟夫环模型,环长度为n,先输出的是后n/2个数字
注意:由题目可知,可能的环长为2-30,但每个计算量大,打表,否则超时
约瑟夫环是从自己开始数n个
#include <cstdio>
#include <string.h>
#include <cstdlib>
#include <cmath>
#include <ctgmath>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void pack(vector<int> &m,int a){
for(int i=1; i <= a*2; i++){
m.push_back(i);
}
}
int main()
{
vector<int> m;
int ma[16] = {0};
int a;
for(a=1;a<=14;a++){
int t = 0,gap = 1;//gap的初始值也要注意
for(;;gap++){
pack(m,a);
int num = (gap-1)%(m.size());//关键代码
while( (m[num]>=(a+1)) && (m[num]<=(2*a)) ){
m.erase(m.begin()+num);
t++;
num = (num+gap-1)%(m.size()) ;
}//判断是不是最大的那一半数字
if(t>=a) {
m.clear();
break;
}
m.clear();
t=0;
}
ma[a]=gap;
}
int t ;
while(scanf("%d",&t),t){
cout<<ma[t]<<endl;
}
return 0;
}
形成约瑟夫环关键代码
int t = 0,gap = 1;//gap的初始值也要注意
for(;;gap++){
pack(m,a);//vector填充
int num = (gap-1)%(m.size());//关键代码//gap刚开始剪不剪1要弄清楚
while( (m[num]>=(a+1)) && (m[num]<=(2*a)) ){//没有判断条件就是一个普通的约瑟夫环
m.erase(m.begin()+num);
t++;
num = (num+gap-1)%(m.size()) ;//从刚刚单的那个下标开始,加(gao-1)M 长度,就是下一个的位置
}//判断是不是最大的那一半数字
if(t>=a) {
m.clear();
break;
}
m.clear();
t=0;
}
本文介绍了一种解决约瑟夫环问题的方法——打表法,通过预先计算特定情况来快速解决问题,适用于环长度不大于30的情况。文章详细展示了如何利用C++实现这一算法,并特别关注于如何高效地输出后半部分数字。
1609

被折叠的 条评论
为什么被折叠?



