码迷,mamicode.com
首页 > 其他好文 > 详细

看过去小程序的疑惑

时间:2016-05-07 08:22:37      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

问题 C 最大乘积
时间限制: 1 Sec 内存限制: 128 MB
[提交]
题目描述

输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列,如果这个最大的乘积不是正数,则输出-1

输入

输入包括多组数据,每组数据第一行为正整数n,第二行为n个元素组成的序列S,1<=n<=18,-10<=Si<=10

输出

输出每组数据的结果后换行

样例输入
3
2 4 -3
5
2 5 -1 2 -1
样例输出
8

20

本来不是很难得一道题 可是连续的应该不是必须从首位开始的吧?

接下来解释为什么会有这个问题

先贴oj通过的程序(copy别人的此处引用)

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
int a[30];
int i,j;
int main()
{
    int n;
    long long  w;
    long long ans;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        ans=0;
        for(i=0; i<n; i++)
        {
            w=1;
            for(j=0; j<n; j++)
            {
                w*=a[j];
                if(w>ans)
                    ans=w;
            }
        }
        if(ans>0)
cout<<ans<<endl;
        else
            printf("-1\n");
 }
    return 0;
}
不懂第二个for循环有什么作用 既然接下来的for循环每次都是j=0开始 那么执行n次并无意义

而且只能找到从首位开始乘积最大的子序列 不可以找到中间最大的子序列


接下来是改的第三个for循环

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
int a[30];
int i,j;
int main()
{
    int n;
    long long  w;
    long long ans;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0; i<n; i++)
            scanf("%d",&a[i]);
        ans=0;
        for(i=0; i<n; i++)
        {
            w=1;
            for(j=i; j<n; j++)
            {
                w*=a[j];
                if(w>ans)
                    ans=w;
            }
        }
        if(ans>0)
cout<<ans<<endl;
        else
            printf("-1\n");
    }
    return 0;
}

改为j=i开始 保证了最大子序列不包括开头

接下来帖自己写的

#include<stdio.h>
#define N 0
int main(){
    int a[20]={N},zero[20]={0};
    int num0,num,num1,fu1,fu2,most,num10,most1,result;
    int n,m,k;
    while   (scanf("%d",&n)!=EOF){
    num0=num=num1=m=fu1=fu2=num10=0;
    most=most1=1;
    k=1;
    result=0;
    while(k<=n){
        scanf("%d",&a[k]);
        if(a[k]==0){
            zero[++m]=k;////0所在的位置
            num0++;///0的个数
        }
        if(a[k]==10)
            num10++;
        k++;
    }
    if((n==1 && a[1]<1) || num0==n)
        printf("-1\n");
    else
    {//else0
        if(num10==n){
            printf("1");
            for(int b=0;b<n;b++)
            printf("0");
            printf("\n");}
        else{
    zero[++m]=n+1;
    for(int i=0;i<num0+1;i++){//for0
        for(int j=zero[i]+1;j<zero[i+1];j++){//for1
            if(a[j]<0)
                num++;///0与0之间的负数个数
            else
                num1++;
        }//for1

        if((num%2)==0 && (num1!=0 || num!=0)){//if1////当两个0中间的数的负数为偶数且有非0数
            for(int p=zero[i]+1;p<zero[i+1];p++){//for2
                most=most*a[p];////求出当前积
            }//for2
        }//if1
        else{//else1
            if((num%2)!=0 && (zero[i+1]-zero[i])>2){
            for(int q=zero[i]+1;q<zero[i+1];q++){///for3
                if(a[q]<0)
                    fu1++;
                if(fu1<num)
                    most=most*a[q];
                if(a[zero[i+1]-q+zero[i]]<0)
                    fu2++;
                if(fu2<num)
                    most1=most1*a[zero[i-1]-q+zero[i]];
            }//for3
            if(most<most1)
                most=most1;
            }
            else
                most=a[zero[i]+1];
        } //else1
        if(result<most )
            result=most;
        most=most1=1;
        num=num1=0;
    }//for0
    if(result>0)
    printf("%d\n",result);
    else
        printf("-1\n");
    num10=0;
        }
    }//else0
    }
return 0;
}

可是oj只能通过第一个

如果输入

9

0 -1 0 2 3 0 7 8 0

oj通过的程序得到的是-1

改过的和自己的 得到的是56

是我没读懂题 还是为什么

看过去小程序的疑惑

标签:

原文地址:http://blog.csdn.net/lfanchenyu/article/details/51334485

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!