codeforces 1042C Array Product【构造】

题目:戳这里

题意:n个数,两种操作,第一种是a[i]*a[j],删掉a[i],第一种是直接删除a[i](只能用一次)剩下的数序列号不变。操作n-1次,使最后剩下的那个数最大化。

解题思路:

正数之间全用操作1得到的结果最大。

负数的个数如果是偶数,全用操作1最后得到的也最大。如果是奇数,那最大的那个负数(贪心的思想)就要进行特殊操作,具体怎么操作要看后面有没有0,如果有0就用操作1去乘,没有就用操作2直接给这个数删了。

有0的话就把所有的0乘最后一个0,然后把最后一个0删了。

附ac代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 5e5 + 10;
 5 const int inf = 5e5 + 10;
 6 struct nod
 7 {
 8     ll a;
 9     int id;
10 }nu[maxn];
11 bool cmp(nod x, nod y)
12 {
13     return x.a < y.a;
14 }
15 int main() {
16     int n;
17     scanf("%d", &n);
18     for(int i = 1; i <= n; ++i)
19     {
20         scanf("%lld", &nu[i].a);
21         nu[i].id = i;
22     }
23     sort(nu + 1, nu + 1 + n, cmp);
24     int cntm = 0;
25     int lastz = 0;
26     int cntop = 0;
27     int firstp = 0;
28     int firstz = 0;
29 
30     for(int i = 1; i <= n; ++i)
31     {
32         if(nu[i].a < 0) ++cntm;
33         if(nu[i].a == 0)
34         {
35            if(!firstz) firstz = i;
36             lastz = i;
37         }
38         if(nu[i].a > 0)
39         {
40             firstp = i;
41             break;
42         }
43     }
44     if(cntm & 1)
45     {
46         if(lastz)   firstz = cntm;
47         else    printf("2 %d\n", nu[cntm].id);
48         --cntm;
49     }
50     for(int i = 1; i < cntm; ++i)
51     {
52         printf("1 %d %d\n", nu[i].id, nu[cntm].id);
53     }
54     for(int i = firstz; i < lastz; ++i)
55     {
56         printf("1 %d %d\n", nu[i].id, nu[i + 1].id);
57     }
58     if(lastz && (cntm || firstp))//这里wa了好多发
59     {
60         printf("2 %d\n", nu[lastz].id);
61 
62     }
63     if(firstp)
64     {
65         if(cntm)
66         {
67             printf("1 %d %d\n", nu[cntm].id, nu[n].id);
68         }
69         for(int i = firstp; i < n; ++i)
70         {
71             printf("1 %d %d\n", nu[i].id, nu[n].id);
72         }
73     }
74     return 0;
75 }
View Code

 

posted @ 2018-09-18 22:10  euzmin  阅读(331)  评论(0编辑  收藏  举报