# D

# 题目大意

给你一个 A=(a1,...,an)A=(a_1,...,a_n),问你是否可以重排列成 B=(b1,...,bn)B=(b_1,...,b_n) 使得 BB 是一个等比数列

# 数据范围

  • 1T1051 \le T \le 10^5
  • 2N2×1052 \le N \le 2 \times 10^5
  • 109ai109-10^9 \le a_i \le 10^9

# 题解

AA 可能有:

  • 纯正数
  • 纯负数
  • 正数负数交替

需要注意的是,正数负数交替的情况

  • 必须满足, max(正数个数, 负数个数) - min(正数个数, 负数个数) <= 1
  • 注意,等比数列的公比 DD 的绝对值,可能 1\ge 1 也可能 <1< 1
    • 如果 |D| >= 1 的话,那么序列绝对值应该是升序的
    • 如果 |D| < 1 的话,那么序列绝对值应该是降序的

下面是我的屎山代码

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
int n;
vector<int> a;

bool check(vector<int>& a) {
for (int i = 3; i <= n; i++)
if (a[i] * a[i - 2] != a[i - 1] * a[i - 1])
return false;
return true;
}

void solve () {
cin >> n, a = vector<int>(n + 1);
vector<int> num[2];

for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] > 0)
num[0].push_back(a[i]);
else if (a[i] < 0)
num[1].push_back(a[i]);
}

if (n <= 2) {
cout << "Yes\n";
return;
}

if (num[1].empty() || num[0].empty()) {
sort(a.begin() + 1, a.end());

cout << (check(a) ? "Yes" : "No") << '\n';
}
else {
bool flag1 = 0;
int idx = (num[0].size() >= num[1].size() ? 0 : 1);
if (num[idx].size() - num[1 - idx].size() > 1) {
cout << "No\n";
return;
}

sort(num[0].begin(), num[0].end());
sort(num[1].begin(), num[1].end(), [](int x, int y)
{ return x > y; });

a = vector<int>(1);

for (int i = 0; i < num[1 - idx].size(); i++)
a.push_back(num[idx][i]), a.push_back(num[1 - idx][i]);

if (num[idx].size() != num[1 - idx].size())
a.push_back(num[idx].back());
// num[idx][0] -> num[1 - idx][0] -> num[idx][1] -> num[1 - idx][1]

flag1 = check(a);
if (flag1) {
cout << "Yes\n";
return;
}

sort(num[1].begin(), num[1].end());
sort(num[0].begin(), num[0].end(), [](int x, int y)
{ return x > y; });
a = vector<int>(1);
for (int i = 0; i < num[1 - idx].size(); i++)
a.push_back(num[idx][i]), a.push_back(num[1 - idx][i]);

if (num[idx].size() != num[1 - idx].size())
a.push_back(num[idx].back());

cout << (check(a) ? "Yes" : "No") << '\n';
}
}

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

duoxichangan 微信支付

微信支付

duoxichangan 支付宝

支付宝