Raggedy, Raggedy: Difference between revisions

From programming_contest
Jump to navigation Jump to search
imported>Kmk21
Created page with "= Introduction = This asks you to format monospaced text by splitting it across lines of max length L such that the sum of squares of the difference between the actual line le..."
 
imported>Kmk21
No edit summary
 
Line 3: Line 3:


= Solutions=
= Solutions=
== Idea ==
== DP ==
Do some basic algebra, and compute the desired result.
Dimensions
=== Gotchas ===
* word you're on
be sure to use %.3f to print to three places
Values
* the minimum sum of squares
* length of the last line (for path recovery)
Relation
For each word you attempt to add word N to the end of the paragraph, you must iterate over all possible lines ending with N ("N-1 N", "N-2 N-1 N"...), up until you hit max line length L. The value is the minimum of(L-length(candidate last line) + dp(N-<words on candidate last line>). Ensure you record the line length when you find a minimum so you can actually build the paragraph later.
 
Construct the paragraph backwards, storing the correct number of words for each line, and then print them out in the correct order.
=== Code ===
=== Code ===


Line 12: Line 18:
<syntaxhighlight line lang="java">
<syntaxhighlight line lang="java">
import java.util.*;
import java.util.*;
public class a {
public class b {
Scanner in=new Scanner(System.in);
Scanner in=new Scanner(System.in);
public static void main(String[] args) {
public static void main(String[] args) {
new a().go();
new b().go();
}
}
private void go() {
private void go() {
while(true){
while(true){
double te=in.nextDouble(),tr=in.nextDouble();
int n=in.nextInt();
if(te==0&&tr==0)break;
if(n==0)break;
System.out.printf("%.3f\n", Math.sqrt((1-tr/te*tr/te)));
in.nextLine();
ArrayList<String> words=new ArrayList<String>();
while(true){
String line=in.nextLine();
if(line.equals(""))break;
Scanner s=new Scanner(line);
while(s.hasNext())words.add(s.next());
}
int[] lengths=new int[words.size()];
for(int i=0;i<words.size();i++)lengths[i]=words.get(i).length();
int[][] dp=new int[words.size()+1][2];
for(int i=0;i<=words.size();i++)dp[i][0]=Integer.MAX_VALUE;
dp[0][0]=0;
for(int i=0;i<words.size();i++){
int len=0;
for(int j=1;j<=i+1;j++){
len+=lengths[i-j+1]+1;
if(len-1>n)break;
int r=dp[i-j+1][0];
if(i<dp.length-2)r+=(n-len+1)*(n-len+1);
if(r<dp[i+1][0]){
dp[i+1][0]=r;
dp[i+1][1]=j;
}
}
}
ArrayList<Integer> lens=new ArrayList<Integer>();
for(int on=words.size()-1;on>=0;){
lens.add(dp[on+1][1]);
on-=dp[on+1][1];
}
Collections.reverse(lens);
Queue<String> q=new LinkedList<String>(words);
for(int i:lens){
String out="";
for(int j=0;j<i;j++)out+=" "+q.poll();
System.out.println(out.substring(1));
}
System.out.println("===");
}
}
}
}
Line 29: Line 73:
[[Category:midatl2011]]
[[Category:midatl2011]]
[[Category:ICPC Problems]]
[[Category:ICPC Problems]]
[[category:printf]]
[[category:input]]
[[Category:Algorithm Trivial]]
[[category:output]]
[[Category:Implementation Trivial]]
[[category:Dynamic Programming]]
[[Category:Algorithm Medium]]
[[Category:Implementation Hard]]

Latest revision as of 23:59, 16 February 2015

Introduction

This asks you to format monospaced text by splitting it across lines of max length L such that the sum of squares of the difference between the actual line lengths and L is mininal.

Solutions

DP

Dimensions

  • word you're on

Values

  • the minimum sum of squares
  • length of the last line (for path recovery)

Relation For each word you attempt to add word N to the end of the paragraph, you must iterate over all possible lines ending with N ("N-1 N", "N-2 N-1 N"...), up until you hit max line length L. The value is the minimum of(L-length(candidate last line) + dp(N-<words on candidate last line>). Ensure you record the line length when you find a minimum so you can actually build the paragraph later.

Construct the paragraph backwards, storing the correct number of words for each line, and then print them out in the correct order.

Code

Solution - Java

import java.util.*;
public class b {
	Scanner in=new Scanner(System.in);
	public static void main(String[] args) {
		new b().go();
	}
	private void go() {
		while(true){
			int n=in.nextInt();
			if(n==0)break;
			in.nextLine();
			ArrayList<String> words=new ArrayList<String>();
			while(true){
				String line=in.nextLine();
				if(line.equals(""))break;
				Scanner s=new Scanner(line);
				while(s.hasNext())words.add(s.next());
			}
			int[] lengths=new int[words.size()];
			for(int i=0;i<words.size();i++)lengths[i]=words.get(i).length();
			int[][] dp=new int[words.size()+1][2];
			for(int i=0;i<=words.size();i++)dp[i][0]=Integer.MAX_VALUE;
			dp[0][0]=0;
			for(int i=0;i<words.size();i++){
				int len=0;
				for(int j=1;j<=i+1;j++){
					len+=lengths[i-j+1]+1;
					if(len-1>n)break;
					int r=dp[i-j+1][0];
					if(i<dp.length-2)r+=(n-len+1)*(n-len+1);
					if(r<dp[i+1][0]){
						dp[i+1][0]=r;
						dp[i+1][1]=j;
					}
				}
			}
			ArrayList<Integer> lens=new ArrayList<Integer>();
			for(int on=words.size()-1;on>=0;){
				lens.add(dp[on+1][1]);
				on-=dp[on+1][1];
			}
			Collections.reverse(lens);
			Queue<String> q=new LinkedList<String>(words);
			for(int i:lens){
				String out="";
				for(int j=0;j<i;j++)out+=" "+q.poll();
				System.out.println(out.substring(1));
			}
			System.out.println("===");
		}
	}
}