Cod sursa(job #1504394)

Utilizator andreipurdilaAndrei Purdila andreipurdila Data 17 octombrie 2015 18:09:21
Problema Subsecventa de suma maxima Scor 50
Compilator java Status done
Runda Arhiva educationala Marime 4.38 kb
/**
 * Created by andrei on 17.10.2015.
 */
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

    private class MaximumSubarrayResult {
        private Long sum = 0L;
        private int startIndex = -1;
        private int endIndex = -1;

        public MaximumSubarrayResult( Long sum, int startIndex, int endIndex ) {
            this.sum = sum;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
        }

        public Long getSum() {
            return sum;
        }

        public int getStartIndex() {
            return startIndex;
        }

        public int getEndIndex() {
            return endIndex;
        }
    }

    public static void main( String[] args ) throws IOException {
//        java.util.Scanner sc = new java.util.Scanner( new FileReader( "ssm.in" ) );
//        sc.nextInt();
//        List <Integer> values = new ArrayList<>(  );
//        while ( sc.hasNextInt() ) {
//            values.add( sc.nextInt() );
//        }
        //MaximumSubarrayResult result = new Main().maximumSum( );
        maximumSum();
//        PrintWriter pw = new PrintWriter(  "ssm.out" );
//        pw.print( result.getSum() + " " + ( result.getStartIndex() + 1 ) + " " + ( result.getEndIndex() + 1 ) );
//        pw.close();

    }



    public MaximumSubarrayResult maximumSumDivideEtImpera (List <Integer> values, int start, int end ) {
        if ( start == end ) {
            return new MaximumSubarrayResult( new Long(values.get( start )), start, end );
        }
        int midd = ( start + end ) / 2;
        MaximumSubarrayResult leftMax = new Main().maximumSumDivideEtImpera( values, start, midd );
        MaximumSubarrayResult rightMax = new Main().maximumSumDivideEtImpera( values, midd + 1, end );
        MaximumSubarrayResult crossMax = new Main().crossMaximumSum( values, start, end );

        if ( leftMax.getSum() >= rightMax.getSum() && leftMax.getSum() >= crossMax.getSum() ) {
            return leftMax;
        } else if ( rightMax.getSum() >= leftMax.getSum() && rightMax.getSum() >= crossMax.getSum() ) {
            return rightMax;
        } else {
            return crossMax;
        }
    }

    public MaximumSubarrayResult crossMaximumSum (List <Integer> values, int start, int end) {
        Long leftMaxSum = Long.MIN_VALUE;
        Long rightMaxSum = Long.MIN_VALUE;
        int middle = ( start + end ) / 2;
        int maxLeftPosition = middle;
        int maxRightPosition = middle + 1;
        Long sum = 0L;
        for ( int i = middle; i >= 0; --i ) {
            sum += values.get( i );
            if ( sum > leftMaxSum ) {
                leftMaxSum = sum;
                maxLeftPosition = i;
            }
        }

        sum = 0L;
        for ( int i = middle + 1; i <= end; ++i ) {
            sum += values.get( i );
            if ( sum > rightMaxSum ) {
                rightMaxSum = sum;
                maxRightPosition = i;
            }
        }

        return new MaximumSubarrayResult( leftMaxSum + rightMaxSum, maxLeftPosition, maxRightPosition );
    }

    public static void maximumSum() throws FileNotFoundException {
        PrintWriter pw = new PrintWriter(  "ssm.out" );
        //pw.close();
        java.util.Scanner sc = new Scanner( new FileReader( "ssm.in" ) );
        int limit = sc.nextInt();
        if (limit == 0) {
            //return new MaximumSubarrayResult( 0L, 0, 0 );
            pw.print( 0 + " " + 0 + " " + 0 );
            pw.close();
            System.exit( 0 );
        } else {
            long sum = sc.nextInt();
            long max = Long.MIN_VALUE;
            int startIndex = 0;
            int endIndex = 0;
            int maxStartIndex = 0;
            int maxEndIndex = 0;
            for (int i = 1; i < limit; ++i ) {
                int nextValue = sc.nextInt();
                if ( sum + nextValue >= nextValue ) {
                    endIndex = i;
                    sum += nextValue;
                } else {
                    sum = nextValue;
                    startIndex = i;
                    endIndex = i;
                }
                if ( sum > max ) {
                    max = sum;
                    maxStartIndex = startIndex;
                    maxEndIndex = endIndex;
                }
            }
            pw.print( max + " " + (maxStartIndex + 1) + " " + (maxEndIndex + 1) );
            pw.close();
        }
    }
}