Cod sursa(job #1504276)

Utilizator andreipurdilaAndrei Purdila andreipurdila Data 17 octombrie 2015 16:14:36
Problema Subsecventa de suma maxima Scor 0
Compilator java Status done
Runda Arhiva educationala Marime 3.51 kb
/**
 * Created by andrei on 17.10.2015.
 */
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MaximumSubarray {

    public 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 {
//        List< Integer > values = Arrays.asList( 13, -3, -25, 20, -3, -16, -23, 18, 20,
//                -7, 12, -5, -22, 15, -4 );
        //System.out.println( MaximumSubarray.class.getProtectionDomain().getCodeSource().getLocation().getPath() );
        java.util.Scanner sc = new java.util.Scanner( new File( "ssm.in" ) );
        sc.nextInt();
        List <Integer> values = new ArrayList<>(  );
        while ( sc.hasNextInt() ) {
            values.add( sc.nextInt() );
        }
        MaximumSubarrayResult result = new MaximumSubarray().maximumSum( values, 0, values.size() - 1 );
//        System.out.println( "Sum: " + result.getSum() + "    startIndex: " + ( result.getStartIndex() + 1 ) +
//                "   endIndex: " + ( result.getEndIndex() + 1 ) );

        PrintWriter pw = new PrintWriter( new File( "ssm.out" ) );
        pw.print( result.getSum() + " " + (result.getStartIndex() + 1) + " " + (result.getEndIndex() + 1) );
        pw.close();
    }



    public MaximumSubarrayResult maximumSum (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 MaximumSubarray().maximumSum( values, start, midd );
        MaximumSubarrayResult rightMax = new MaximumSubarray().maximumSum( values, midd + 1, end );
        MaximumSubarrayResult crossMax = new MaximumSubarray().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 );
    }
}