题目描述
小 Z 组织了一个小游戏,这个游戏是这样的:现在有 n 个凳子排成了一个圈,我们按照顺时针的方式将这些凳子依次编号为 1,2,⋯,n。我们从编号为 s 的凳子开始,每次先顺时针数 m 个凳子,将第 m 个凳子搬走,然后再逆时针数 k 个凳子,将第 k 个凳子搬走。每次都这样先顺时针数 m 个,再逆时针数 k 个,直到只剩下一个凳子,直接搬走。
现在,小 Z 想知道这 n 个凳子的搬走顺序。
输入格式
输入共四行,每行一个数,分别表示题目中的 n,s,m,k。
输出格式
一行 n 个整数,按照顺序输出依次搬走的凳子编号,每个编号之间有一个空格。
输入输出样例
输入 #1
8 1 3 2
输出 #1
3 1 5 2 7 4 6 8
说明/提示
1≤n≤1000,1≤s,m,k≤n。
C++解法
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,s,m,k;
int a[1005] , right = 1, curr, pos;
cin >> n >> s >> m >>k;
curr = n;
for (int i = 1; i <= n; i++)
{
a[i] = i;
}
a[n+1] = n+1;
m--;
while(curr >= 1) {
// 顺时针
if (right) {
s += m;
right--;
} else {
// 逆时针
s -= k;
right++;
}
s = (s + curr)%curr;
if (s == 0)
s+=curr;
// pos = (s-1)%curr + 1;
pos = s;
cout << a[pos] << " ";
curr--;
cout<< s << " "<< curr;
for (int i=pos;i<=curr;i++){
// cout<<a[i+1] << " ";
a[i] = a[i + 1];
}
// for (int i = 1; i<= curr;i++) {
// cout<<a[i] << " ";
// }
cout << endl;
}
return 0;
}
https://oi-wiki.org/misc/josephus/
## 质数问题
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 2022年每月天数(平年)
const int month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 质数月份:2,3,5,7,11
const vector<int> prime_months = {2, 3, 5, 7, 11};
// 质数小时:0-23中的质数
const vector<int> prime_hours = {2, 3, 5, 7, 11, 13, 17, 19, 23};
// 质数分钟/秒:0-59中的质数
const vector<int> prime_min_sec = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
// 质数日:1-31中的质数
const vector<int> prime_days = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
// 存储所有质数时间的时间戳(从2022-01-01 00:00:00开始的秒数)
vector<long long> all_prime_times;
// 计算时间戳
long long get_timestamp(int month, int day, int hour, int minute, int second, const vector<long long>& prefix) {
// 计算从1月1日开始的天数
long long days = (month == 1) ? 0 : prefix[month - 2];
days += day - 1;
// 计算总秒数
return days * 86400LL + hour * 3600LL + minute * 60LL + second;
}
// 初始化函数:生成2022年所有质数时间点的时间戳
void init() {
// 计算每月的前缀和(累计天数)
vector<long long> prefix(12, 0);
for (int i = 1; i < 12; i++) {
prefix[i] = prefix[i - 1] + month_days[i - 1];
}
// 生成所有质数时间点
for (int month : prime_months) {
int days_in_month = month_days[month - 1];
for (int day : prime_days) {
if (day > days_in_month) continue; // 跳过无效日期
for (int hour : prime_hours) {
for (int minute : prime_min_sec) {
for (int second : prime_min_sec) {
long long ts = get_timestamp(month, day, hour, minute, second, prefix);
all_prime_times.push_back(ts);
}
}
}
}
}
// 排序时间戳(虽然按顺序生成,但确保有序)
sort(all_prime_times.begin(), all_prime_times.end());
}
int main() {
// 初始化:生成所有质数时间点
init();
int T;
cin >> T;
// 计算每月的前缀和(用于查询)
vector<long long> prefix(12, 0);
for (int i = 1; i < 12; i++) {
prefix[i] = prefix[i - 1] + month_days[i - 1];
}
while (T--) {
int a, b, c, d, e;
int u, v, w, x, y;
cin >> a >> b >> c >> d >> e;
cin >> u >> v >> w >> x >> y;
// 计算起始时间和终止时间的时间戳
long long start_ts = get_timestamp(a, b, c, d, e, prefix);
long long end_ts = get_timestamp(u, v, w, x, y, prefix);
// 二分查找第一个大于等于start_ts的位置
auto it1 = lower_bound(all_prime_times.begin(), all_prime_times.end(), start_ts);
// 二分查找第一个大于end_ts的位置
auto it2 = upper_bound(all_prime_times.begin(), all_prime_times.end(), end_ts);
// 计算区间内的质数时间点数量
cout << (it2 - it1) << endl;
}
return 0;
}
## C++设置

-std=c++11
-static-libstdc++ -static-libgcc
浙公网安备 33010602011771号