题意翻译
你有一个长度为的数组
。
你可以进行任意次操作,每一次可以选择一个数,并让
变成
。
你的目标是使得这个数组每一个元素的乘积最大,请求出这个最大的价值,并输出这个最大价值的序列。
输入格式
第一行包含一个整数,表示数组的长度。
第二行包含个整数,分别为
,表示数组中的元素。
输出格式
输出仅有一行,包含个整数,表示这个最大的价值序列。
Input & Output 's examples
Input 's eg 1
4 2 2 2 2
Output 's eg 1
-3 -3 -3 -3
Input 's eg 2
1 0
Output 's eg 2
0
Input 's eg 3
3 -3 -3 2
Output 's eg 3
-3 -3 2
数据范围和约定
对于的数据,保证
,
分析
一道简单贪心题。
手推几组样例后不难看出,一个数如果操作两次之后等于没操作。则题目就变成了对于每一个,让你选择是否进行操作,使得乘积最大。
可以注意到,若是一个正数,则
一定大于
。
又根据初中数学可得,偶数个负数的乘积一定是正数。
因此,对于是偶数的情况我们直接全部变成负数即可。
而对于为奇数的情况,不难看出,奇数减
一定是偶数。因此,我们只需要选择一个数不进行操作即可。
显然,我们要选择的是绝对值最大的数。
时间复杂度为,跑过
的数据绰绰有余。
剩下的见代码注释。
Code[Accepted]
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<vector> #include<algorithm> #include<iomanip> #include<cstdlib> #include<cctype> #include<cmath> #define ll long long #define I inline #define N 100001 using namespace std; ll n , a[N]; ll maxn = 0; ll p = 0x3f3f3f3f; int main(){ cin >> n; for(int i = 1; i <= n; i ++){ cin >> a[i]; if(a[i] >= 0){ //输入时将所有的数都变成负数 a[i] = -a[i] - 1; } maxn = min(maxn , a[i]); if(maxn == a[i]){ //记录绝对值最大的数的位置 p = i; } } if(n % 2 == 0){ //如果n为偶数,直接输出序列即可。 for(int i = 1; i <= n; i ++){ cout << a[i] << " "; } return 0; } else{ for(int i = 1; i <= n; i ++){ //否则的话,修改绝对值最大的数。 if(p == i){ cout << -a[i] - 1 << " "; } else{ cout << a[i] << " "; } } } return 0; }