很有意思的题啊~~
核心问题,如何快速判断合数~~
然后你想啊,那么多数字满足条件的一定非常多,那么只要这个数字有因子,就一定是合数。
而且题目并没有需要你输出前k个数字,所以可以这样……
定义一个数字叫:新合数,新合数是,这个数字有一个因子在2~1000之间。
显然,新合数一定是合数~ 那么我就不判断是否是非素数了,只要是新合数就可以啦~~~~ 这样程序巨快,飞速解决small的数据
那么large呢? 1e32…… 理论上也是可以这样做的,只不过套一个bigint的模板,或者用py或者java
当然还有更简单的方法~
一个数字100010100????01010011这样的数字转化为k进制的时候,进行一系列的乘,加运算…… 我们需要知道这个在彻底转化完成后,是否可以被p整除, 那么在转化的过程中就可以进行计算了……简单吧!
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> #include <cmath> #include <vector> #include <bitset> using namespace std; #define LL long long void nextInt(int &x) { scanf("%d", &x); } void nextInt(int &x, int &y) { scanf("%d%d", &x, &y); } int n, j; LL qz; void init() { nextInt(n, j); qz = 1; qz |= (1 << (n - 1)); } int f[2000]; int output[1000]; bool check(long long arg) { bitset<60> a = arg; for (int jinzhi = 2; jinzhi <= 10; ++ jinzhi) { memset(f, 0, sizeof(f)); for (int i = n - 1; i >= 0; -- i) { for (int j = 2; j <= 1000; ++ j) { if (a[i] == 0) { f[j] = (f[j] * jinzhi) % j; } else { f[j] = (f[j] * jinzhi + 1) % j; } } } for (int i = 2; i <= 1000; ++ i) if (f[i] == 0) { output[jinzhi] = i; goto here; } //没有执行到break? return false;//arg在jinzhi的进制下,是素数 here:; } for (int i = n - 1; i >= 0; -- i) printf("%d", a[i] == 1); printf(" "); for (int i = 2; i <= 9; ++ i) printf("%d ", output[i]); printf("%d\n", output[10]); return true; } void doit() { int ans = 0; for (LL i = 0; i < (1 << (n - 2)); ++ i) { if (check((i << 1LL) | qz)) ++ ans; if (ans == j) break; } } int main() { freopen("C-large.in","r",stdin); freopen("C-large.out","w",stdout); LL sb; scanf("%lld", &sb); for (int i = 1; i <= sb; ++ i) { printf("Case #%d:\n", i); init(); doit(); } return 0; }