题目描述:
E. Epic Fail of a Genie
Time Limit: Unknown ms
Memory Limit: 65536KB
64-bit integer IO format: %I64d Java class name: (Any)
Submit Status PID: 49355
Input/Output: standard input/output
Aladdin had found a new shiny lamp and has started polishing it with his hands. Suddenly a mysterious genie appeared from within and offered Aladdin to fulfill any of his three wishes. Genie had a very subtle humor that made Aladdin very sceptical about him. Aladdin didn’t believe that genie was so powerful that could do anything he had wished and asked him to become a mouse. The genie did that without hesitation. Then Aladdin asked genie to become a mouse pad. Genie didn’t like this kind of wish but had to submit. Finally Aladdin tested genie’s abilities in math: he had to choose a nonempty subset giving the maximum product from the given set of numbers. Genie was shocked. Math was his Achilles’ heel, however he was able to contact anyone on earth to help him. You are a secret weapon of the genie — help him solve the test and avoid this epic fail. This is the last chance for the genie: he’ll be forever jailed in the lamp if his new master doesn’t trust him.
Input
The first line of input contains an integer N (2 ≤ N ≤ 104) — the cardinality of a set of numbers.
The second line of input contains N floating-point numbers with absolute value not more than 106. The fractional part of each number does not contain more than two digits.
Output
The first line of the output should contain a single integer M — the total number of numbers that genie should choose from the set.
The second line of output should contain 1-based indexes of these numbers. Indexes must be sorted in ascending order. If multiple solutions exist please output the one with the minimal subset cardinality. If there are still several suitable solutions output any of them.
Sample Input
Input
7
1 3 0 -1 -2 0.5 3
Output
4
2 4 5 7
题解:
第一反应当然是dp,维护前面的一个正数的最大值,和一个负数的绝对值的最大值.但是乘起来的数太大了.最后看昂神的代码,可以取log,因为取log的缘故,那么我们只进行绝对值的运算,用一个tag来记录这个数的符号.注意,在昂神队的代码中有一个*100000-1的过程,因为log之后的数有点小,不如全部放大一点.而且,初始化的0初始化为-INF,他们选择的是-1e60.
解法二(2):其实是有贪心性质的,当时能搞出这个思路队友还是挺牛的:) 就是取大于1的然后分类讨论balabala..
重点:
dp的方法:取log 同时乘一个数 tag打正负 初始化0的-INF
贪心的思想
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)
typedef long long ll;
using namespace std;
const double eps = 1e-7;
struct info
{
int num, id;
info(int _num = 0, int _id = 0)
{
num = _num;
id = _id;
}
bool operator < (const info b) const
{
return num < b.num;
}
};
vector<info> bigPos, bigNa, smallPos, smallNa, zero;
vector<int> ans;
int n;
void outPut()
{
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for(int i = 0;i<ans.size();i++)
printf("%d%c", ans[i], (i==ans.size()-1?'\n':' '));
}
void solve()
{
bigPos.clear();
bigNa.clear();
smallPos.clear();
smallNa.clear();
zero.clear();
///
for(int i = 1;i<=n;i++)
{
double x;
int t;
scanf("%lf", &x);
if(x>eps)
t = ((x*100)+eps);
else if(x < -eps)
t = ((x*100)-eps);
else
t = 0;
if(t > 100)
bigPos.push_back(info(t, i));
else if(t < -100)
bigNa.push_back(info(t, i));
else if(t > 0)
smallPos.push_back(info(t, i));
else if(t < 0)
smallNa.push_back(info(t, i));
else
zero.push_back(info(t, i));
}
sort(bigPos.begin(), bigPos.end());
sort(smallPos.begin(), smallPos.end());
sort(bigNa.begin(), bigNa.end());
sort(smallNa.begin(), smallNa.end());
sort(zero.begin(), zero.end());
ans.clear();
if(bigNa.size()%2==0)
{
for(int i = 0;i<bigNa.size();i++)
ans.push_back(bigNa[i].id);
for(int i = 0;i<bigPos.size();i++)
ans.push_back(bigPos[i].id);
if(ans.size()!=0)
{
outPut();
return;
}
if(smallNa.size() >= 2 || smallPos.size() >= 1)
{
ll pos = -1;
ll na = -1;
if(smallPos.size() >= 1)
pos = (ll)smallPos[smallPos.size()-1].num*(ll)100;
if(smallNa.size() >= 2)
na = (ll)smallNa[0].num*(ll)smallNa[1].num;
if(na > pos)
{
ans.push_back(smallNa[0].id);
ans.push_back(smallNa[1].id);
outPut();
return;
}
else
{
ans.push_back(smallPos[smallPos.size()-1].id);
outPut();
return;
}
}
else
{
if(zero.size() >= 1)
{
ans.push_back(zero[0].id);
outPut();
return;
}
else
{
///
ans.push_back(smallNa[smallNa.size()-1].id);
outPut();
return;
}
}
}
else
{
for(int i = 0;i<bigNa.size() - 1;i++)
ans.push_back(bigNa[i].id);
for(int i = 0;i<bigPos.size();i++)
ans.push_back(bigPos[i].id);
if(ans.size()!=0)
{
if(smallNa.size() >= 1)
{
ll tmp = (ll)smallNa[0].num*(ll)bigNa[bigNa.size()-1].num;
if(tmp > 10000)
{
ans.push_back(bigNa[bigNa.size()-1].id);
ans.push_back(smallNa[0].id);
}
}
outPut();
return;
}
else
{
if(smallNa.size()>=1 || smallPos.size() >= 1)
{
//printf("%d %d---\n", smallNa[0].num, bigNa[bigNa.size()-1].num);
ll pos = -1, na = -1;
if(smallNa.size() >= 1)
na = (ll)smallNa[0].num*(ll)bigNa[bigNa.size()-1].num;
if(smallPos.size() >= 1)
pos = (ll)smallPos[smallPos.size()-1].num*(ll)100;
if(na > pos)
{
ans.push_back(bigNa[bigNa.size()-1].id);
ans.push_back(smallNa[0].id);
outPut();
return;
}
else
{
ans.push_back(smallPos[smallPos.size()-1].id);
outPut();
return;
}
}
else
{
if(zero.size()>=1)
{
ans.push_back(zero[0].id);
outPut();
return;
}
else
{
ans.push_back(bigNa[bigNa.size()-1].id);
outPut();
return;
}
}
}
}
}
int main()
{
// freopen("13Min.txt", "r", stdin);
//freopen("1out.txt", "w", stdout);
while(scanf("%d", &n) != EOF)
solve();
return 0;
}