hdu 5504 GT and sequence(思维,逻辑,脑洞)

解决一个关于选择整数序列中元素以获得最大乘积的问题,考虑正数、负数及零的存在,通过分类讨论和排序策略实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GT and sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2417    Accepted Submission(s): 549


Problem Description
You are given a sequence of N integers.

You should choose some numbers(at least one),and make the product of them as big as possible.

It guaranteed that **the absolute value of** any product of the numbers you choose in the initial sequence will not bigger than2631.
 


Input
In the first line there is a number T (test numbers).

For each test,in the first line there is a number N,and in the next line there are N numbers.

1T1000
1N62

You'd better print the enter in the last line when you hack others.

You'd better not print space in the last of each line when you hack others.
 


Output
For each test case,output the answer.
 


Sample Input
1 3 1 2 3
 


Sample Output
6

一道比较恶心的题目,这个题的特点就是让你看着,咋看咋简单,怎么看都是水题,然后怎么写都是WA,能够1A的选手要么是逻辑性特别强,要么就是老兵油子。。。像我这种小白,不WA个三百次五百次的不长记性。。。

这个题目有很多坑。。。

首先我们知道,如果是正数,怎么乘都行,但是如果有负数的情况,就要分奇数个负数还是偶数个负数来处理,我们在输入的时候运用一个小小的技巧躲过这个小小的问题:

并且顺便介绍各个变量的用处。

        if(n==0)//如果是0个数,当然要输出1.
        {
            printf("0\n");
            continue;
        }
        int cont=0;//记录负数的个数。
        int biaoji=0;//记录是否有0的出现。
        int youzhengshu=0;//记录是否有正数。
        __int64 sum=1;
       // printf("yes\n");
        for(int i=0;i<n;i++)
        {
            __int64  k;//这里没有给出小数据的范围,我们用I64的输入更加保守。
           scanf("%I64d",&k);
           if(k<0)a[cont++]=k;//a数组里边存的就是负数啦~
           if(k==0)biaoji=1;
           if(k>0)
           {
               sum*=k;//如果是正数,就直接乘就行了
               youzhengshu=1;//因为我初始化sum=1,一会可能要有输出0的时候,我们这里标记一下。
           }
        }
        sort(a,a+n);//我们对负数进行排序处理,如果是偶数个数,一会直接乘上就行,否则我们要抛弃绝对值最小的那个。

然后接下来就要判断几种特殊的情况,少一种都会WA....

 

        if(biaoji==1&&cont==0&&youzhengshu==0)//很多个0的输入.
        {
            printf("0\n");
            continue;
        }
        if(cont==1&&youzhengshu==0&&biaoji==0)//只有一个负数的输入。
        {
            printf("%d\n",a[0]);
            continue;
        }
        if(cont==1&&biaoji==1&&youzhengshu==0)//只有一个负数且有0的输入
        {
            printf("0\n");
            continue;
        }
        if(n==1&&biaoji==1)//只有一个0的输入。
        {
            printf("0\n");
            continue;
        }

最后我们乘上偶数个负数,得到最终结果:

 

        if(cont!=0)
        {
            if(cont%2==0)
            {
                for(int i=0;i<cont;i++)
                {
                    sum*=a[i];
                }
            }
            if(cont%2==1)
            {
                for(int i=0;i<cont-1;i++)
                {
                    sum*=a[i];
                }
            }
        }


最后上简洁版的完整AC代码:


#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
__int64 a[200];
__int64 b[200];
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        int cont=0;
        int biaoji=0;
        int youzhengshu=0;
        __int64 sum=1;
       // printf("yes\n");
        for(int i=0;i<n;i++)
        {
            __int64  k;
           scanf("%I64d",&k);
           if(k<0)a[cont++]=k;
           if(k==0)biaoji=1;
           if(k>0)
           {
               sum*=k;
               youzhengshu=1;
           }
        }
        sort(a,a+n);
        if(biaoji==1&&cont==0&&youzhengshu==0)//很多个0的输入.
        {
            printf("0\n");
            continue;
        }
        if(cont==1&&youzhengshu==0&&biaoji==0)//只有一个负数的输入。
        {
            printf("%d\n",a[0]);
            continue;
        }
        if(cont==1&&biaoji==1&&youzhengshu==0)//只有一个负数且有0的输入
        {
            printf("0\n");
            continue;
        }
        if(n==1&&biaoji==1)//只有一个0的输入。
        {
            printf("0\n");
            continue;
        }
        if(cont!=0)
        {
            if(cont%2==0)
            {
                for(int i=0;i<cont;i++)
                {
                    sum*=a[i];
                }
            }
            if(cont%2==1)
            {
                for(int i=0;i<cont-1;i++)
                {
                    sum*=a[i];
                }
            }
        }
        printf("%I64d\n",sum);
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值