Sunday, December 5, 2010

USACO - Prime Cryptarithm

Prime Cryptarithm
The following cryptarithm is a multiplication problem that can be solved by substituting digits from a specified set of N digits into the positions marked with *. If the set of prime digits {2,3,5,7} is selected, the cryptarithm is called a PRIME CRYPTARITHM.
* * *
   x    * *
    -------
      * * *         <-- partial product 1
    * * *           <-- partial product 2
    -------
    * * * *
Digits can appear only in places marked by `*'. Of course, leading zeroes are not allowed. Note that the 'partial products' are as taught in USA schools. The first partial product is the product of the final digit of the second number and the top number. The second partial product is the product of the first digit of the second number and the top number.
Write a program that will find all solutions to the cryptarithm above for any subset of digits from the set {1,2,3,4,5,6,7,8,9}.

PROGRAM NAME: crypt1

INPUT FORMAT

Line 1: N, the number of digits that will be used
Line 2: N space separated digits with which to solve the cryptarithm

SAMPLE INPUT (file crypt1.in)

5
2 3 4 6 8

OUTPUT FORMAT

A single line with the total number of unique solutions. Here is the single solution for the sample input:
2 2 2
    x   2 2
     ------
      4 4 4
    4 4 4
  ---------
    4 8 8 4

SAMPLE OUTPUT (file crypt1.out)

1

Ad hoc - iteration - simulation

There are two ways to solve this problem.
First you can easily iterate from a=100 to a=999 and from b=10 to b=99 in nested for loops, then you can produce the product of a and b and check whether the digits of a, b and a*b are valid or not, if yes increment your output. This approach runs in O(1000 * 100).
Second you can set the digits of a and b, a[0], a[1], a[2] and b[0], b[1] from your input, in this way you don't have to check the validity of a[i] and b[i] and then produce the product of a and b, and now check whether the digits of a*b are valid or not. This approach runs in O(9^5) that is a little better but harder to implement.

USACO - Barn Repair

Barn Repair

It was a dark and stormy night that ripped the roof and gates off the stalls that hold Farmer John's cows. Happily, many of the cows were on vacation, so the barn was not completely full.
The cows spend the night in stalls that are arranged adjacent to each other in a long line. Some stalls have cows in them; some do not. All stalls are the same width.
Farmer John must quickly erect new boards in front of the stalls, since the doors were lost. His new lumber supplier will supply him boards of any length he wishes, but the supplier can only deliver a small number of total boards. Farmer John wishes to minimize the total length of the boards he must purchase.
Given M (1 <= M <= 50), the maximum number of boards that can be purchased; S (1 <= S <= 200), the total number of stalls; C (1 <= C <= S) the number of cows in the stalls, and the C occupied stall numbers (1 <= stall_number <= S), calculate the minimum number of stalls that must be blocked in order to block all the stalls that have cows in them.
Print your answer as the total number of stalls blocked.

PROGRAM NAME: barn1

INPUT FORMAT

Line 1: M, S, and C (space separated)
Lines 2-C+1: Each line contains one integer, the number of an occupied stall.

SAMPLE INPUT (file barn1.in)

4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43

OUTPUT FORMAT

A single line with one integer that represents the total number of stalls blocked.

SAMPLE OUTPUT (file barn1.out)

25
[One minimum arrangement is one board covering stalls 3-8, one covering 14-21, one covering 25-31, and one covering 40-43.]




 Greedy - sorting - finding maximum difference each time

Here you have a problem that you have C numbers and you want to split them in M-1 places so remains M sequences that the sum of the difference between the first and last number is each sequence becomes minimum.
For example something like this :
a1 a2 a3 ..... aC
you have to split this sequence in M-1 places so that :
aK1-a1+1    +    aK3-aK2+1   +    aK4-aK3+1   + ..... +     aC-aKM-1 +1   is minimized.
First you have to sort the numbers. Then each time you have to find the maximum difference between two adjacent numbers and choose it to be the index you want to split your sequence. Do this M-1 times and then you have M sequences that the sum of the differences between the first and last number in each sequence is minimum.

USACO - Mixing Milk

Mixing Milk

Since milk packaging is such a low margin business, it is important to keep the price of the raw product (milk) as low as possible. Help Merry Milk Makers get the milk they need in the cheapest possible manner.
The Merry Milk Makers company has several farmers from which they may buy milk, and each one has a (potentially) different price at which they sell to the milk packing plant. Moreover, as a cow can only produce so much milk a day, the farmers only have so much milk to sell per day. Each day, Merry Milk Makers can purchase an integral amount of milk from each farmer, less than or equal to the farmer's limit.
Given the Merry Milk Makers' daily requirement of milk, along with the cost per gallon and amount of available milk for each farmer, calculate the minimum amount of money that it takes to fulfill the Merry Milk Makers' requirements.
Note: The total milk produced per day by the farmers will be sufficient to meet the demands of the Merry Milk Makers.

PROGRAM NAME: milk

INPUT FORMAT

Line 1: Two integers, N and M.
The first value, N, (0 <= N <= 2,000,000) is the amount of milk that Merry Milk Makers' want per day. The second, M, (0 <= M <= 5,000) is the number of farmers that they may buy from.
Lines 2 through M+1: The next M lines each contain two integers, Pi and Ai.
Pi (0 <= Pi <= 1,000) is price in cents that farmer i charges.
Ai (0 <= Ai <= 2,000,000) is the amount of milk that farmer i can sell to Merry Milk Makers per day.

SAMPLE INPUT (file milk.in)

100 5
5 20
9 40
3 10
8 80
6 30

OUTPUT FORMAT

A single line with a single integer that is the minimum price that Merry Milk Makers can get their milk at for one day.

SAMPLE OUTPUT (file milk.out)

630

Greedy - sorting

This problem is solved using a straight forward greedy algorithm, you can easily see that if you sort the input by prices and buy milk from those who sell milk cheaper, you will result in the optimum answer.
For example in the sample input you can see that : you need 100 gallons of milk and there are 5 farmers available for you to buy milk from. First you buy
10 gallons from the farmer who sells milk 3 cents per gallon, then
20 gallons from the farmer who sells milk 5 cents per gallon, then
30 gallons from the farmer who sells milk 6 cents per gallon, then
40 gallons from the farmer who sells milk 8 cents per gallon ( this farmer has 80 gallons available but you just need 40 gallons to reach 100 gallons each day )
So the answer is 10*3 + 20*5 + 30*6 + 40*8 = 30 + 100 + 180 + 320 = 630

USACO - Transformations

Transformations
A square pattern of size N x N (1 <= N <= 10) black and white square tiles is transformed into another square pattern. Write a program that will recognize the minimum transformation that has been applied to the original pattern given the following list of possible transformations:
  • #1: 90 Degree Rotation: The pattern was rotated clockwise 90 degrees.
  • #2: 180 Degree Rotation: The pattern was rotated clockwise 180 degrees.
  • #3: 270 Degree Rotation: The pattern was rotated clockwise 270 degrees.
  • #4: Reflection: The pattern was reflected horizontally (turned into a mirror image of itself by reflecting around a vertical line in the middle of the image).
  • #5: Combination: The pattern was reflected horizontally and then subjected to one of the rotations (#1-#3).
  • #6: No Change: The original pattern was not changed.
  • #7: Invalid Transformation: The new pattern was not obtained by any of the above methods.
In the case that more than one transform could have been used, choose the one with the minimum number above.

PROGRAM NAME: transform

INPUT FORMAT

Line 1: A single integer, N
Line 2..N+1: N lines of N characters (each either `@' or `-'); this is the square before transformation
Line N+2..2*N+1: N lines of N characters (each either `@' or `-'); this is the square after transformation

SAMPLE INPUT (file transform.in)

3
@-@
---
@@-
@-@
@--
--@

OUTPUT FORMAT

A single line containing the the number from 1 through 7 (described above) that categorizes the transformation required to change from the `before' representation to the `after' representation.

SAMPLE OUTPUT (file transform.out)

1

Ad hoc - string manipulation

In my solution I have 3 funcions f90(), cmp() and reflect()
f90( string [], string [], int ); takes two arrays of string and an integer -the size of arrays- and rotates the grid 90 degrees clockwise and put it into the second array of string
cmp( string [], string [], int ); takes two arrays of string and an integer -the size of arrays- and compares them whether they are equal or not
reflect( string [], string [], int ); takes two arrays of string and an integer -the size of arrays- and reflects the first one round a vertical line and put it into the second one

for rotating 180 and 270 degrees I used 2 or 3 times of f90(), respectively.
read the problem description carefully as it says : "In the case that more than one transform could have been used, choose the one with the minimum number above."

USACO - Palindromic Squares

Palindromic Squares
Rob Kolstad
Palindromes are numbers that read the same forwards as backwards. The number 12321 is a typical palindrome.
Given a number base B (2 <= B <= 20 base 10), print all the integers N (1 <= N <= 300 base 10) such that the square of N is palindromic when expressed in base B; also print the value of that palindromic square. Use the letters 'A', 'B', and so on to represent the digits 10, 11, and so on.
Print both the number and its square in base B.

PROGRAM NAME: palsquare

INPUT FORMAT

A single line with B, the base (specified in base 10).

SAMPLE INPUT (file palsquare.in)

10

OUTPUT FORMAT

Lines with two integers represented in base B. The first integer is the number whose square is palindromic; the second integer is the square itself.

SAMPLE OUTPUT (file palsquare.out)

1 1
2 4
3 9
11 121
22 484
26 676
101 10201
111 12321
121 14641
202 40804
212 44944
264 69696

Brute force - base conversion - palindrome checking

Produce all the squares of numbers from 1 to 300, convert them to base b and check whether they are palindrome or not, if they are, convert the number to base b too and print both the number and it's square that has been converted to base b.
I have two functions in my solution, toBase( int, int ) and isPal( string ). In toBase() function I convert the given number to base b, and in function isPal() I check whether the given string is palindrome or not with two iterators to the beginning and to the end of the string.

USACO - Dual Palindromes

Dual Palindromes
Mario Cruz (Colombia) & Hugo Rickeboer (Argentina)
A number that reads the same from right to left as when read from left to right is called a palindrome. The number 12321 is a palindrome; the number 77778 is not. Of course, palindromes have neither leading nor trailing zeroes, so 0220 is not a palindrome.
The number 21 (base 10) is not palindrome in base 10, but the number 21 (base 10) is, in fact, a palindrome in base 2 (10101).
Write a program that reads two numbers (expressed in base 10):
  • N (1 <= N <= 15)
  • S (0 < S < 10000)
and then finds and prints (in base 10) the first N numbers strictly greater than S that are palindromic when written in two or more number bases (2 <= base <= 10). Solutions to this problem do not require manipulating integers larger than the standard 32 bits.

PROGRAM NAME: dualpal

INPUT FORMAT

A single line with space separated integers N and S.

SAMPLE INPUT (file dualpal.in)

3 25

OUTPUT FORMAT

N lines, each with a base 10 number that is palindromic when expressed in at least two of the bases 2..10. The numbers should be listed in order from smallest to largest.

SAMPLE OUTPUT (file dualpal.out)

26
27
28


Brute force search - base conversion - palindrome checking

Easily iterate from s+1 and each time convert the number to all the bases and check whether they are palindrome or not, if the number is palindrome in more than 2 bases, print that number and decrement n.
when I want to convert a number to base b, I used strings, it's simpler to check whether it is palindrome or not, and for checking whether the given string is palindrome or not I use two pointers to the beginning and to the end of the string and check whether they are equal or not, whenever a position is found that they are not equal I return false, otherwise I return true at the end.

USACO - Name That Number

Name That Number
Among the large Wisconsin cattle ranchers, it is customary to brand cows with serial numbers to please the Accounting Department. The cow hands don't appreciate the advantage of this filing system, though, and wish to call the members of their herd by a pleasing name rather than saying, "C'mon, #4734, get along."
Help the poor cowhands out by writing a program that will translate the brand serial number of a cow into possible names uniquely associated with that serial number. Since the cow hands all have cellular saddle phones these days, use the standard Touch-Tone(R) telephone keypad mapping to get from numbers to letters (except for "Q" and "Z"):
2: A,B,C     5: J,K,L    8: T,U,V
3: D,E,F     6: M,N,O    9: W,X,Y
4: G,H,I     7: P,R,S
Acceptable names for cattle are provided to you in a file named "dict.txt", which contains a list of fewer than 5,000 acceptable cattle names (all letters capitalized). Take a cow's brand number and report which of all the possible words to which that number maps are in the given dictionary which is supplied as dict.txt in the grading environment (and is sorted into ascending order).
For instance, the brand number 4734 produces all the following names:
GPDG GPDH GPDI GPEG GPEH GPEI GPFG GPFH GPFI GRDG GRDH GRDI
GREG GREH GREI GRFG GRFH GRFI GSDG GSDH GSDI GSEG GSEH GSEI
GSFG GSFH GSFI HPDG HPDH HPDI HPEG HPEH HPEI HPFG HPFH HPFI
HRDG HRDH HRDI HREG HREH HREI HRFG HRFH HRFI HSDG HSDH HSDI
HSEG HSEH HSEI HSFG HSFH HSFI IPDG IPDH IPDI IPEG IPEH IPEI
IPFG IPFH IPFI IRDG IRDH IRDI IREG IREH IREI IRFG IRFH IRFI
ISDG ISDH ISDI ISEG ISEH ISEI ISFG ISFH ISFI
As it happens, the only one of these 81 names that is in the list of valid names is "GREG".
Write a program that is given the brand number of a cow and prints all the valid names that can be generated from that brand number or ``NONE'' if there are no valid names. Serial numbers can be as many as a dozen digits long.

PROGRAM NAME: namenum

INPUT FORMAT

A single line with a number from 1 through 12 digits in length.

SAMPLE INPUT (file namenum.in)

4734

OUTPUT FORMAT

A list of valid names that can be generated from the input, one per line, in ascending alphabetical order.

SAMPLE OUTPUT (file namenum.out)

GREG


String - complete search - using STL map, string & vector
There are two approaches to this problem:
First : since the input number has at most 12 digits and for each digit there are 3 candidates if you build all the possibilities and then search them in the dictionary the order of your program will become
O(3^12 * nlog(n)) n = 5000     531441 * 42585 that I think is a little too high to run in the time limit.
Second : you can map all the strings in the dictionary to The explained number, and then easily when you read the input number search that whether you have that number in your map data structure and print all the strings mapped to that number, print "NONE" otherwise.

USACO - Milking Cows

Milking Cows
Three farmers rise at 5 am each morning and head for the barn to milk three cows. The first farmer begins milking his cow at time 300 (measured in seconds after 5 am) and ends at time 1000. The second farmer begins at time 700 and ends at time 1200. The third farmer begins at time 1500 and ends at time 2100. The longest continuous time during which at least one farmer was milking a cow was 900 seconds (from 300 to 1200). The longest time no milking was done, between the beginning and the ending of all milking, was 300 seconds (1500 minus 1200).
Your job is to write a program that will examine a list of beginning and ending times for N (1 <= N <= 5000) farmers milking N cows and compute (in seconds):
  • The longest time interval at least one cow was milked.
  • The longest time interval (after milking starts) during which no cows were being milked.

PROGRAM NAME: milk2

INPUT FORMAT

Line 1: The single integer
Lines 2..N+1: Two non-negative integers less than 1000000, the starting and ending time in seconds after 0500

SAMPLE INPUT (file milk2.in)

3
300 1000
700 1200
1500 2100

OUTPUT FORMAT

A single line with two integers that represent the longest continuous time of milking and the longest idle time.

SAMPLE OUTPUT (file milk2.out)

900 300

Sorting - Ad hoc - iteration with high precision
First sort the elements by the start time of milking then iterate and keep track of maxEnd and minStart till now, if the current times have intersection with the minStart and maxEnd, then update your maxEnd time, else change the minStart and maxEnd to the current times (start[i], end[i]), this is for the longest time that at list one cow is being milked.
For the longest time that no cow is being milked, easily do the same, if the current start[cur] > maxEnd, you have a gap here, so keep track of start[cur]-maxEnd and update minStart and maxEnd.
At the end choose the maximum between your values.

TJU - 1415 - Ferry Loading II

problem statement

greedy - ad hoc - simulation

you have to check whether you can load each time n cars or not, if not the first load must be m%n and the rest loads n cars.
then you have to iterate to see when a load comes back are there n other cars ready or not and then decide what to do next.
if they are ready ferry loads the cars and leaves soon, otherwise ferry has to wait for the n-th car to come and this time is calculated.

Thursday, December 2, 2010

TJU - 1477 - binary numbers

problem statement

bits - binary presentation of N

Easily in this problem you have to find out the locations of 1's in the binary presentation of a number N.
I iterate from i=0 to 2^i <= 1000000 and each time check whether ( N & 2^i != 0 ) or not and print i if result is true.
1 << i
00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000

USACO - Prime Palindromes

I just skimmed the problem statement and panicked of the high boundary of the input, but something inside told me don't worry everyth...