Prime permutations
The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.
There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.
What 12-digit number do you form by concatenating the three terms in this sequence?
题目:
1487, 4817, 8147 这个序列,每个比前一个递增 3330,而且这个序列有两个特点:1. 序列中的每个数都是质数。 2. 每个四位数都是其他数字的一种排列。
1,2,3 位组成的三个质数的序列中没有具有以上性质的。但是还有另外一个四位的递增序列满足这个性质。
如果将这另外一个序列的三个数连接起来,组成的 12 位数字是多少?
题目找的是3个4位数,并且这3个4位数满足以下条件:
1.每个比前面一个递增3330
2.每个数都是质数
3.并且这3个数的每位数的集合是相同的
那么条件一很好满足,条件二利用线性筛找出10000以下的质数,条件3利用2进制来存储位置上的数,将十进制的数的每位映射到二进制中的位置来表示;
例如4123将他的每位数字映射在二进制中,
而4231用二进制映射,也是上面途中的这样;
为什么一个数需要用两位,因为在4位数中如果这个数为质数,那相同的数最多存在3个,所以两位二进制刚好是3;
那么有了上面这个方法,就很好去判断条件3,就将这3个数分别映射入二进制中,并判读他们映射后的二进制是否相等就可以了;
映射二进制代码就是:
int map_num(int x) { int num = 0; while (x){ num += (1 << (2 * (x % 10)));//因为每两位来表示一个数所以需要乘二 x /= 10; } return num; }
最终实现代码为:
#include <stdio.h> #define MAX_N 10000 int prime[MAX_N + 5]; int isprime[MAX_N + 5]; void init() {//线性筛 for (int i = 2; 2 * i <= MAX_N; i++) { if (!isprime[i]) prime[++prime[0]] = i; for (int j = 1; i * prime[j] <= MAX_N; j++) { isprime[i * prime[j]] = 1; if (i % prime[j] == 0) break; } } return ; } int is_num(int a) { int num = 0, s = a; while (s) { num += (1 << (2 *(s % 10))); s /= 10; } return num; } void int_to_char(int a, int b, int c) { char buff[15] = {0}; int len = 0; len += sprintf(buff + len, "%d", a); len += sprintf(buff + len, "%d", b); len += sprintf(buff + len, "%d", c); printf("%s\n", buff); return ; } int main() { init(); for (int i = 1000; i <= MAX_N; i++) { if (isprime[i]) continue; //如果当前枚举的数都不为质数继续循环 if (i == 1487) continue; int b = i + 3330; int c = i + 6660; if (isprime[b] || isprime[c]) continue;//如果b, c有一个不为质数继续循环 if (is_num(b) != is_num(c)) continue;//如果b, c映射结果不相等继续循环 if (is_num(i) != is_num(b)) continue; int_to_char(i, b, c); break; } return 0; }
最终答案:296962999629