AT_abc413_d题解

题目传送门
AtCoder D-Make Geometric Sequence

题面:
给你一个数组\(a\),请问能否重排列\(a\)使其成为一个等比数列。

做法:

分类讨论:

对于公比\(q\)进行分类讨论:
首先可以排除\(q = 0\) 因为\(a_i \neq 0\)
接着如果\(|q| = 1\),那么所有的\(a_i\)绝对值一定相等,这时如果正负数个数相差\(\leq 1\) 或者所有数字同号,那么可以排列为等比数列,否则不能。
然后如果\(q > 0\),说明所有的\(a_i\)同号,可以直接将\(a\)的所有元素进行排序,并判断是否是等比数列以来判断。
最后如果\(q < 0\),说明\(a\)中有的是正数,有的是负数,且正数和负数的个数相差不超过\(1\),可以将\(a\)的所有元素按照绝对值从小到大排序,并判断是否是等比数列以来判断。

注意:\(|q| = 1\)时别忘了判断所有数字同号,我因为这个狂调半天。。。

#include <bits/stdc++.h>
using namespace std;
int a[200001];
bool cmp(int p1, int p2)
{
    return abs(p1) < abs(p2); // 根据绝对值比较
}
void solve()
{
    int n, cnt1 = 0, cnt2 = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] > 0)
        {
            cnt1++; // 正数的个数
        }
        else
        {
            cnt2++; // 负数的个数
        }
    }
    bool flagg = false;
    for (int i = 1; i <= n; i++)
    {
        if (abs(a[i]) != abs(a[1]))
        {
            flagg = true;
            break;
        }
    }
    if (!flagg) // 特判绝对值全部相等
    {
        if (abs(cnt1 - cnt2) <= 1 || cnt1 == 0 || cnt2 == 0) // 呃呃
        {
            cout << "Yes" << endl;
            return;
        }
        else
        {
            cout << "No" << endl;
            return;
        }
    }
    if (cnt1 != 0 && cnt2 != 0) // 正负都有
    {
        sort(a + 1, a + n + 1, cmp);
    }
    else // 全部同号
    {
        sort(a + 1, a + n + 1);
    }

    bool flag = false;
    for (int i = 2; i < n; i++)
    {
        if (1ll * a[i] * a[i] != 1ll * a[i - 1] * a[i + 1]) // 除法尽量改成乘法
        {
            flag = true;
            break;
        }
    }
    if (!flag)
    {
        cout << "Yes" << endl;
    }
    else
    {
        cout << "No" << endl;
    }
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}


posted @ 2025-07-07 16:01  MichaelZeng  阅读(11)  评论(0)    收藏  举报