题目 | Even Sum Triplet
AtCoder Regular Contest 155
C - Even Sum Triplet
https://atcoder.jp/contests/arc155/tasks/arc155_c
Time Limit: 2 sec / Memory Limit: 1024 MB
Score :
Problem Statement
You are given integer sequences of length
You may perform the following operation any number of times:
- Choose an integer
such that is even. Then, rearrange , , as you like.
Determine whether it is possible to make equal .
Constraints
- All values in the input are integers.
Input
The input is given from Standard Input in the following format:
Output
If it is possible to make
Sample Input 1
5
1 2 3 4 5
3 1 2 4 5
Sample Output 1
Yes
If you choose
Now Yes
.
Sample Input 2
5
1 2 4 6 5
5 1 4 2 6
Sample Output 2
No
Sample Input 3
9
2 10 4 3 6 2 6 8 5
2 4 10 3 8 6 6 2 5
Sample Output 3
Yes
题解
该操作是可逆的
如果数列
如何确认 与 之间的关系
如果我们可以将
- 能通过操作互相转化的数列,标准型一定相同
- 不能通过操作互相转化的数列,标准型一定不同
那么我们的比较就变得非常方便了,即:
:输出 Yes :输出 No
如何设计一个标准型
由于数列中元素的顺序是无意义的,所以我们想到用排序来消除这种差异,但是由于题目限制,我们是无法任意排序的。
- 当整个数列全是奇数时
数列无法进行任何操作,因此其本身就是标准型。
- 当整个数列不存在距离
的奇数时(即任意 个相邻的数,奇数个数 )
奇数无法做任何移动,各个奇数将数列分成了若干个偶数段,若偶数段的长度
通过上述特性,我们将每个能够任意变换顺序的偶数段进行排序,结果作为标准型。
- 存在距离
的奇数时(即存在 个相邻的数,奇数个数 )
两个奇数可以通过操作任意左右移动,如右移的方式如下:
若碰到了更多奇数,活动区间可以变得更长如
同时也能对这串连续的奇数进行排序,只需借助一个偶数即可:
- 可将一个偶数移动到奇数中的任意位置,而不改变奇数顺序
- 偶数两旁的奇数可调换位置:
- 综上,可以交换任意相邻奇数的位置,使用冒泡排序就能将完成排序
如果偶数数量
通过上述特性,我们将奇数放在前面并对其排序,偶数放在后面,若偶数数量
算法流程
判断
- 若
的类型不同:输出 No 若
的类型相同若类型为全奇数
相同:输出 Yes 不同:输出 No
若类型为无相邻或有相邻
的标准型相同:输出 Yes 的标准型不同:输出 No
代码
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
// 计算类型: 0-无相邻 1-有相邻 2-全奇数
int type(vector<int> &v)
{
int last = -3, cnt_odd = 0, ans = 0;
for (int i = 0; i < v.size(); i++)
{
if (v[i] % 2)
{
if (i - last <= 2)
ans = 1;
last = i;
cnt_odd++;
}
}
if (cnt_odd == v.size())
ans = 2;
return ans;
}
// 计算标准型
vector<int> norm(vector<int> &v, int type)
{
if (type == 0)
{
int last = -1;
for (int i = 0; i < v.size(); i++)
{
if (v[i] % 2)
{
if (i - last >= 4)
sort(v.begin() + last + 1, v.begin() + i);
last = i;
}
}
sort(v.begin() + last + 1, v.end());
return v;
}
else if (type == 1)
{
vector<int> odd, even;
for (auto ele : v)
{
if (ele % 2)
odd.push_back(ele);
else
even.push_back(ele);
}
sort(odd.begin(), odd.end());
if (even.size() >= 3)
sort(even.begin(), even.end());
odd.insert(odd.end(), even.begin(), even.end());
return odd;
}
return v;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int N;
cin >> N;
vector<int> A(N), B(N);
for (int i = 0; i < N; i++)
cin >> A[i];
for (int i = 0; i < N; i++)
cin >> B[i];
int ia = type(A), ib = type(B); // 计算类型
if (ia != ib) // 类型不同直接判假
cout << "No" << endl;
else if (ia == 2) // 若均为全奇数类型,比对原型
cout << (A == B ? "Yes" : "No") << endl;
else // 若为无相邻或有相邻类型,比对标准型
cout << (norm(A, ia) == norm(B, ib) ? "Yes" : "No") << endl;
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi