import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Scanner; /** * Solution to Barbells * * @author vanb */ public class barbells_vanb { private static Scanner sc; private static PrintStream ps; /** Bars & Plates */ private int bars[], plates[]; /** A useful value: Half of the sum of weights of all plates */ private int halftotal; /** * We'll represent a combination of plates as a bitmap. * This HashMap will map a sum to all of the plate combinations that sum to that value. */ private HashMap> bitmaps; /** * Produce all subsets of plates * * @param level How many plates are left to choose * @param bitmap Plates which have already been chosen * @param sum Sum of plates which have already been chosen */ private void subsets( int level, int bitmap, int sum ) { // We want the same weight on both sides of the bar. // So, if this sum is greater than half the total of all plates, // there won't be enough plates to put on the other side of the bar, // and no solution is possible. if( sum <= halftotal ) { // If we've figured out which plates are in our subset for all plates... if( level==0 ) { // Record this bitmap representation of this subset of plates with its sum. List maps = bitmaps.get( sum ); if( maps==null ) { maps = new ArrayList(); bitmaps.put( sum, maps ); } maps.add( bitmap ); } else { --level; // Don't use this plate subsets( level, bitmap, sum ); // Use this plate (add it into the bitmap) subsets( level, bitmap|(1<>(p*p); // Read in the weights of the bars bars = new int[b]; for( int i=0; i weights = new HashSet(); // Go through all of the weights of subsets of plates for( int wt : bitmaps.keySet() ) { // See if we can find two mutually exclusive subsets of weights which both have this sum. // If so, then we can put them on opposite sides of the bar, and have a solution. boolean found = false; List maps = bitmaps.get( wt ); for( int b1 : maps ) for( int b2 : maps ) { if( (b1 & b2) == 0 ) found = true; } // If we have a set of plates that we can put on a bar, // the go through all of the bars and get the combined weight. if( found ) { for( int bar : bars ) weights.add( wt + wt + bar ); } } // Sort the weights and print them in sorted order Integer wts[] = (Integer[])weights.toArray( new Integer[weights.size()] ); Arrays.sort( wts ); for( int wt : wts ) ps.println( wt ); } /** * Main! * * @param args Command-line args (not used) * @throws Exception */ public static void main( String[] args ) throws Exception { sc = new Scanner( System.in ); ps = System.out; new barbells_vanb().doit(); } }