小红的质数数组(A组,B组)
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
小红有一个数组,这个数组每一对相邻的元素的和都是质数。
但是小紫偷偷的把数组中的一对 axa_xax 和 ax+1a_{x+1}ax+1 进行了交换,你能找出是 xxx 是多少吗?
输入描述:
第一行输入一个整数 n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105) 表示数组长度。 第二行输入 nnn 个整数表示数组 a(1≤ai≤105)a(1 \leq a_i \leq 10^5)a(1≤ai≤105) 。
输出描述:
输出一个整数表示答案,如果找不到 xxx ,或者有多个答案,则输出 -1。
示例1
输入
复制3 1 3 2
3 1 3 2
输出
复制2
2
说明
小红的数组为1 2 3,小紫交换了第2,3个数,因此答案为2。
import java.util.*;
public class Main {
// 定义最大范围
static final int MAXN = 200005;
// 标记数组,用于标记是否为素数
static boolean[] isprime = new boolean[MAXN];
// 存储素数的数组
static int[] prime = new int[MAXN];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 素数计数器
int cnt = 0;
// 埃拉托斯特尼筛法生成素数表
Arrays.fill(isprime,true);
for (int i = 2; i*i < MAXN; i++) {
if (isprime[i]) {
prime[++cnt] = i;
for (int j = i + i; j < MAXN; j += i) {
isprime[j] = false;
}
}
}
// 读取数组长度
int n = scanner.nextInt();
// 存储交换次数
int ans = 0;
// 存储交换位置
int res = 0;
// 定义数组
int[] a = new int[n + 1];
// 读取数组元素
for (int i = 1; i <= n; i++) {
a[i] = scanner.nextInt();
}
// 遍历数组
for (int i = 1; i < n; i++) {
int flag = a[i] + a[i + 1];
if (!isprime[flag]) {
ans = i + 1;
res++;
if (i + 2 > n) {
System.out.println(-1);
return;
}
// 交换元素
int temp = a[i + 1];
a[i + 1] = a[i + 2];
a[i + 2] = temp;
}
flag = a[i] + a[i + 1];
if (!isprime[flag]) {
System.out.println(-1);
return;
}
}
if (res == 1) {
System.out.println(ans);
} else {
System.out.println(-1);
}
scanner.close();
}
}
- 利用埃拉托斯特尼筛法(Sieve of Eratosthenes)生成 2 到 200000 之间的素数表。
- 读取一个整数
n
和长度为n
的整数数组a
。- 遍历数组,检查相邻元素之和是否为素数。若不是素数,则尝试交换当前元素和下一个元素的位置,再次检查相邻元素之和是否为素数。
- 根据交换次数和结果输出相应信息。如果交换次数为 1,则输出交换操作的位置;否则输出 -1。
埃拉托斯特尼筛法(Sieve of Eratosthenes)是一种用于找出一定范围内所有素数(质数)的经典算法,由古希腊数学家埃拉托斯特尼提出。该算法的核心思想是从 2 开始,将每个素数的倍数标记为合数,最终未被标记的数即为素数。以下为你详细介绍该算法:
算法步骤
假设我们要找出小于等于
n
的所有素数,算法步骤如下:
- 初始化:创建一个布尔类型的数组
isPrime
,长度为n + 1
,并将所有元素初始化为true
。数组的索引代表对应的数字,isPrime[i]
为true
表示i
是素数,为false
表示i
是合数。- 标记 0 和 1:将
isPrime[0]
和isPrime[1]
标记为false
,因为 0 和 1 不是素数。- 筛选过程:
- 从 2 开始,对于每个
i
(isPrime[i]
为true
),将其倍数2 * i
,3 * i
,4 * i
, ... 直到n
标记为false
,因为这些数都是合数。- 继续处理下一个未被标记的数,直到处理完所有小于等于 的数。这是因为如果一个数
n
不是素数,那么它一定有一个小于等于 的因子。- 收集素数:遍历
isPrime
数组,将所有isPrime[i]
为true
的i
收集起来,这些数就是小于等于n
的素数。