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;
}

浙公网安备 33010602011771号