{ "question_id": 7408274, "question_title": "约瑟夫问题", "question_content": "\n
有n人(编号分别为1到n号)围成一圈,从第s人开始报数,报到第m的人出列,然后从出列的下一人重新开始报数,报到第m的人又出列,……,如此重复直到n-1全部出列,只剩最后一个人为止。求剩下的最后一人是谁?\n输入\n一行,三个整数n,m,s,(0<=n,m,s<=1000)意义如上。\n输出\n一行,一个正整数,表示最后剩下的人的编号。\n输入样例
\n\n8 3 1
\n输出样例
\n\n7
\n
\n要求从第s个数开始,数m个出列,第s个不出列
", "difficulty": "困难", "answer_id": 53358508, "answer_content": "\n#include <iostream>\n \nvoid JosePhus(int n, int m, int start) {\n int i, *arr = new int[n]; // 动态分配数组\n int count = 1;; // 保存当前已站出来的人数\n for(i = 0;i < n; i++) // 初始化,把各位置号存入数组中\n arr[i] = i + 1;\n int sum = n;\n //输出参考 printf("出列顺序为:");\n while(count < n) { // 出列顺序\n start--; // 因为数组下标从0开始,所以要减1\n int index = (start+m-1) % sum;//记录第count次出列的下标 \n //输出参考 std::cout << arr[index] << " "; // 输出当前要站出来的人的位置号\n for(i = index; i < sum-1; i++)//出列相当于人数少了一个,循环上限为sum-1\n arr[i] = arr[i+1]; // 把位置号前移\n start = index + 1;//第count+1次开始位置为上次出列下标位置+1\n sum--;//总人数减一 \n count++;//出列人数+1 \n }\n std::cout<< arr[0] <<"\\n";//最后剩下的第一个元素为最后留下的人\n}\n \nint main(int argc, const char * argv[]) {\n int n, m, start; // n:人数 m:数到多少出列 start:开始位置\n \n std::cout << "请输入n,m,start:\\n";\n while(std::cin >> n >> m >> start) {\n JosePhus(n, m, start); // 调用解决约瑟夫问题的函数\n std::cout << "请输入n,m,start:\\n";\n }\n return 0;\n}
\n\n", "tag_name": "c++", "cpp": "#include