• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
P5440 【XR-2】奇迹 思维+筛法

P5440 【XR-2】奇迹

题目

P5440 【XR-2】奇迹

思路 思维+筛法

​ 第一次做的时候思路是暴力搜索,但是这样在代码上和时间复杂度上都是比较高的,后来看题解才知道可以先打表,虽然打表的题做的很多,但是做这道题还是没有想到,可能在思考上太少了。

​ 我们可以枚举把满足条件的数存储到数组中,然后在对每个输入的数进行检查-可以代替任何字符,其余位则进行比较,遍历整个数组。

复杂度上是最应该考虑的问题:

​ 初始化打表\(1e5\), 打表完有\(5e4\)满足条件,因为询问\(T \le 10\), 所以加上比较总的复杂度不超过\(5e6\), 做这道题绰绰有余。

Code

#include <iostream>
#include <vector>

using i64 = long long;

int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int pday[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};

std::vector<int> b, a;

bool prime(int x) {
	if(x < 2) return false;
	for(int i = 2; i <= x / i; i ++) {
		if(x % i == 0) return false;
	}
	return true;
}

void init() {
	for(int i = 1; i <= 12; i ++) {
		for(int j = 0; pday[j] <= day[i]; j ++) {
			if(prime(i * 100 + pday[j])) {
				b.push_back(i * 100 + pday[j]);
			}
		}
	}

	for(int i = 1; i <= 9999; i ++) {
		if(((!(i % 4) && i % 100) ||!(i % 400)) && prime(i * 10000 + 229)) {
			a.push_back(i * 10000 + 229);
		}
	}

	for(int i = 1; i <= 9999; i ++) {
		for(int j = 0; j < b.size(); j ++) {
			if(prime(i * 10000 + b[j])) {
				a.push_back(i * 10000 + b[j]);
			}
		}
	}
}


void solve() {
	std::string t;

	std::cin >> t;
	int ans = 0;

	for(int i = 0; i < a.size(); i ++) {
		bool flag = 1;
		int k = a[i];
		for(int j = 7; j >= 0 && flag; j --, k /= 10) {
			if(t[j] != '-' && k % 10 != t[j] - '0') {
				flag = 0;
			}
		}
		if(flag) ans ++;
	}

	std::cout << ans << "\n";
}

int main() {
	init();

	int _;

	std::cin >> _;

	while(_ --) {
		solve();
	}
}
posted on 2023-02-25 12:39  Jack404  阅读(38)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3