贝隆

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目描述

小 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

说明/提示

1n1000,1s,m,kn。

 

 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++设置

image

 -std=c++11

-static-libstdc++ -static-libgcc

posted on 2025-05-31 16:58  贝隆  阅读(13)  评论(0)    收藏  举报