练习codeforces1535B. Array Reodering

题目如下
B. Array Reodering
time limit per test2 seconds
memory limit per test256 megabytes
You are given an array 𝑎 consisting of 𝑛 integers.

Let's call a pair of indices 𝑖, 𝑗 good if 1≤𝑖<𝑗≤𝑛 and gcd(𝑎𝑖,2𝑎𝑗)>1 (where gcd(𝑥,𝑦) is the greatest common divisor of 𝑥 and 𝑦).

Find the maximum number of good index pairs if you can reorder the array 𝑎 in an arbitrary way.

Input
The first line contains a single integer 𝑡 (1≤𝑡≤1000) — the number of test cases.

The first line of the test case contains a single integer 𝑛 (2≤𝑛≤2000) — the number of elements in the array.

The second line of the test case contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤105).

It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2000.

Output
For each test case, output a single integer — the maximum number of good index pairs if you can reorder the array 𝑎 in an arbitrary way.
题目大意
让我们对现有数组重新排序以达到在1≤𝑖<𝑗≤𝑛的条件下的满足gcd(𝑎𝑖,2𝑎𝑗)>1 指数对(x,y)最多的情况

题目分析
题目中要求满足gcd(𝑎𝑖,2𝑎𝑗)>1最多,其中分别是ai和2aj的公倍数,考虑到2aj一定是偶数,且偶数和偶数的最大公因数一定大于1(*至少为2),所以要是数组中满足条件的(x,y)最多,可以先实现偶数最大化,不是真的改变数组中元素的大小,是在进行gcd的过程中,令aj更多的以奇数的可能出现,所以尽可能的令奇数的索引大于偶数
实现

点击查看代码
for(int i = 0; i < n; i++){
            scanf("%d",&a[i]);
            if(a[i] % 2 == 0){
                even[x++] = a[i];
            }else{
                odd[y++] = a[i];
            }
        }
        int b[2005], k = 0;
        for(int i = 0; i < x; i++)
            b[k++] = even[i];
        for(int i = 0; i < y; i++)
            b[k++] = odd[i];
在输入时进行奇偶的判断分为even和odd两个数组,再重新构造偶数在前奇数在后的数组b,最后计数b数组中的满足条件的(x,y) 完整代码如下
点击查看代码
#include <stdio.h>

int gcd(int a, int b){
    while (b) {
        int t = b;
        b = a % b;
        a = t;
    }
    return a;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        int a[2005];
        int even[2005],odd[2005];
        int count = 0;
        int x = 0,y = 0;
        for(int i = 0; i < n; i++){
            scanf("%d",&a[i]);
            if(a[i] % 2 == 0){
                even[x++] = a[i];
            }else{
                odd[y++] = a[i];
            }
        }
        int b[2005], k = 0;
        for(int i = 0; i < x; i++)
            b[k++] = even[i];
        for(int i = 0; i < y; i++)
            b[k++] = odd[i];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (gcd(b[i], 2 * b[j]) > 1)
                    count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}
posted @ 2025-07-03 21:38  sirro1uta  阅读(29)  评论(0)    收藏  举报